@spacefast/common 0.0.24 → 0.0.26

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (145) hide show
  1. package/brand-assets/LICENSE-Haskoy.txt +93 -0
  2. package/brand-assets/haskoy-latin-variable.woff2 +0 -0
  3. package/brand-assets/spacefast-favicon.svg +4 -4
  4. package/brand-assets/spacefast-sf-full-bleed.svg +3 -3
  5. package/brand-assets/spacefast-wordmark.svg +2 -4
  6. package/dist/agents/connect-targets.js +1 -1
  7. package/dist/agents/private-key-oauth.d.ts +0 -1
  8. package/dist/agents/private-key-oauth.js +46 -63
  9. package/dist/brand-assets-build.js +4 -6
  10. package/dist/brand-assets.d.ts +5 -15
  11. package/dist/brand-assets.js +15 -14
  12. package/dist/config/domains.d.ts +47 -7
  13. package/dist/config/domains.js +65 -10
  14. package/dist/contracts/access.d.ts +3 -3
  15. package/dist/contracts/activity.d.ts +1 -1
  16. package/dist/contracts/activity.js +5 -3
  17. package/dist/contracts/api-keys.js +2 -2
  18. package/dist/contracts/billing.d.ts +2 -1
  19. package/dist/contracts/billing.js +30 -0
  20. package/dist/contracts/builds.d.ts +34 -22
  21. package/dist/contracts/builds.js +18 -6
  22. package/dist/contracts/channels.js +1 -1
  23. package/dist/contracts/comments.d.ts +1 -1
  24. package/dist/contracts/common.d.ts +6 -6
  25. package/dist/contracts/common.js +5 -5
  26. package/dist/contracts/crons.d.ts +35 -0
  27. package/dist/contracts/crons.js +42 -0
  28. package/dist/contracts/device-auth.js +1 -1
  29. package/dist/contracts/docs.d.ts +5 -5
  30. package/dist/contracts/docs.js +2 -2
  31. package/dist/contracts/domains.d.ts +74 -63
  32. package/dist/contracts/domains.js +29 -2
  33. package/dist/contracts/enums.d.ts +3 -2
  34. package/dist/contracts/enums.js +10 -10
  35. package/dist/contracts/error-code-meta.d.ts +14 -0
  36. package/dist/contracts/error-code-meta.js +17 -0
  37. package/dist/contracts/error-codes.d.ts +1 -1
  38. package/dist/contracts/error-codes.js +4 -1
  39. package/dist/contracts/execution.d.ts +15 -12
  40. package/dist/contracts/execution.js +15 -12
  41. package/dist/contracts/feature-lifecycle.d.ts +4 -14
  42. package/dist/contracts/feature-lifecycle.js +0 -11
  43. package/dist/contracts/features.d.ts +33 -47
  44. package/dist/contracts/features.js +27 -20
  45. package/dist/contracts/functions.d.ts +169 -2
  46. package/dist/contracts/functions.js +160 -4
  47. package/dist/contracts/git.d.ts +27 -33
  48. package/dist/contracts/git.js +10 -11
  49. package/dist/contracts/grants.d.ts +2 -2
  50. package/dist/contracts/ids.js +2 -2
  51. package/dist/contracts/internal.d.ts +5 -16
  52. package/dist/contracts/internal.js +2 -12
  53. package/dist/contracts/mcp.d.ts +11 -0
  54. package/dist/contracts/mcp.js +5 -0
  55. package/dist/contracts/me.js +1 -1
  56. package/dist/contracts/operations.d.ts +4 -4
  57. package/dist/contracts/operations.js +2 -2
  58. package/dist/contracts/pages.d.ts +6 -6
  59. package/dist/contracts/plan-policy.d.ts +1 -1
  60. package/dist/contracts/plan-policy.js +1 -1
  61. package/dist/contracts/platform.d.ts +4 -4
  62. package/dist/contracts/publish-archive.d.ts +170 -160
  63. package/dist/contracts/publish-archive.js +8 -1
  64. package/dist/contracts/push-new.d.ts +4 -4
  65. package/dist/contracts/quotas.js +2 -2
  66. package/dist/contracts/repository-connections.d.ts +43 -30
  67. package/dist/contracts/repository-connections.js +11 -3
  68. package/dist/contracts/resources.d.ts +8 -8
  69. package/dist/contracts/resources.js +6 -6
  70. package/dist/contracts/runtime-api.d.ts +103 -56
  71. package/dist/contracts/runtime-api.js +67 -26
  72. package/dist/contracts/runtime-app.d.ts +2 -2
  73. package/dist/contracts/runtime-db.d.ts +6 -6
  74. package/dist/contracts/runtime-db.js +2 -2
  75. package/dist/contracts/runtime-purge.d.ts +8 -0
  76. package/dist/contracts/runtime-purge.js +7 -0
  77. package/dist/contracts/runtime-storage.d.ts +3 -2
  78. package/dist/contracts/runtime-storage.js +2 -1
  79. package/dist/contracts/sf-config-v1.d.ts +48 -10
  80. package/dist/contracts/space-config.d.ts +60 -3
  81. package/dist/contracts/space-config.js +213 -18
  82. package/dist/contracts/spaces.d.ts +55 -74
  83. package/dist/contracts/spaces.js +11 -14
  84. package/dist/contracts/superadmin-spaces.d.ts +9 -9
  85. package/dist/contracts/superadmin-teams.d.ts +2 -2
  86. package/dist/contracts/superadmin-tenants.d.ts +0 -6
  87. package/dist/contracts/superadmin-tenants.js +1 -7
  88. package/dist/contracts/superadmin.d.ts +135 -22
  89. package/dist/contracts/superadmin.js +43 -12
  90. package/dist/contracts/tags.d.ts +21 -21
  91. package/dist/contracts/tags.js +3 -3
  92. package/dist/contracts/teams.d.ts +14 -17
  93. package/dist/contracts/teams.js +6 -6
  94. package/dist/contracts/transfers.js +2 -2
  95. package/dist/contracts/variables.d.ts +4 -4
  96. package/dist/contracts/variables.js +3 -3
  97. package/dist/contracts/webhooks.d.ts +4 -4
  98. package/dist/contracts/zero.d.ts +15 -17
  99. package/dist/contracts/zero.js +12 -12
  100. package/dist/docs/agent-prose.d.ts +1 -1
  101. package/dist/docs/agent-prose.js +11 -14
  102. package/dist/docs/agent-setup.js +5 -2
  103. package/dist/docs/catalog.d.ts +7 -7
  104. package/dist/docs/catalog.js +7 -7
  105. package/dist/docs/error-docs.js +145 -133
  106. package/dist/docs/skills.d.ts +12 -12
  107. package/dist/docs/skills.js +4 -4
  108. package/dist/test-helpers/fetch-stub.js +1 -0
  109. package/dist/utils/build-settings.d.ts +5 -1
  110. package/dist/utils/build-settings.js +82 -10
  111. package/dist/utils/canonical-json.js +1 -0
  112. package/dist/utils/concurrency.js +1 -0
  113. package/dist/utils/credential-policy.js +4 -3
  114. package/dist/utils/dns-instructions.js +9 -9
  115. package/dist/utils/error-code.js +1 -0
  116. package/dist/utils/grant-decision.fixtures.json +2 -2
  117. package/dist/utils/grants.js +3 -1
  118. package/dist/utils/local-space-state.d.ts +8 -11
  119. package/dist/utils/local-space-state.js +13 -24
  120. package/dist/utils/one-shot-replay.d.ts +4 -1
  121. package/dist/utils/page-colors.d.ts +14 -12
  122. package/dist/utils/page-colors.js +15 -13
  123. package/dist/utils/page-fonts.d.ts +1 -1
  124. package/dist/utils/page-fonts.js +11 -18
  125. package/dist/utils/pages.d.ts +20 -1
  126. package/dist/utils/pages.js +22 -9
  127. package/dist/utils/publish-policy.d.ts +7 -0
  128. package/dist/utils/publish-policy.fixtures.json +11 -5
  129. package/dist/utils/publish-policy.js +9 -1
  130. package/dist/utils/query-keys.d.ts +4 -4
  131. package/dist/utils/query-keys.js +2 -2
  132. package/dist/utils/runtime-upload.d.ts +5 -0
  133. package/dist/utils/runtime-upload.js +7 -0
  134. package/dist/utils/secure-local-file.js +5 -16
  135. package/dist/utils/space-config.d.ts +1 -1
  136. package/dist/utils/space-config.js +3 -0
  137. package/dist/utils/static-runtime-policy.d.ts +9 -3
  138. package/dist/utils/static-runtime-policy.fixtures.json +38 -41
  139. package/dist/utils/static-runtime-policy.js +22 -56
  140. package/dist/utils/upload-session.d.ts +4 -1
  141. package/dist/utils/upload-session.js +33 -5
  142. package/dist/utils/version-path.js +1 -1
  143. package/dist/vocabulary.d.ts +8 -8
  144. package/dist/vocabulary.js +31 -20
  145. package/package.json +2 -17
@@ -1,8 +1,8 @@
1
- // Error reference content (internal-docs/platform.md "Global API Conventions"):
1
+ // Error reference content (the platform spec "Global API Conventions"):
2
2
  // every problem document `type` points at `https://spacefast.com/docs/errors/{code}`,
3
3
  // and those pages are GENERATED from this table — one entry per member of
4
4
  // `ERROR_CODES`, asserted complete by the conformance suite so links never rot
5
- // and pages never go missing. apps/www renders the HTML pages and writes the
5
+ // and pages never go missing. The standalone website renders the HTML pages and writes the
6
6
  // `.md` twins from the same entries.
7
7
  import { BRAND } from "../brand.js";
8
8
  import { serviceOrigin } from "../config/domains.js";
@@ -15,7 +15,7 @@ export const ERROR_DOCS = {
15
15
  },
16
16
  account_suspended: {
17
17
  summary: "This account is suspended for a policy or abuse violation and cannot be used.",
18
- fix: "Contact support to review the suspension if you believe it is a mistake.",
18
+ fix: "If you believe the suspension is a mistake, contact support to review it.",
19
19
  },
20
20
  abuse_report_rate_limited: {
21
21
  summary: "Too many abuse reports were submitted from this client in a short window.",
@@ -23,7 +23,7 @@ export const ERROR_DOCS = {
23
23
  },
24
24
  abuse_takedown: {
25
25
  summary: "This space was disabled by an abuse takedown and cannot be served or modified.",
26
- fix: "If you believe this is a mistake, contact support with the space id.",
26
+ fix: "If you believe the takedown is a mistake, contact support with the space id.",
27
27
  },
28
28
  access_denied: {
29
29
  summary: "The authorization request was denied by the user.",
@@ -39,7 +39,7 @@ export const ERROR_DOCS = {
39
39
  },
40
40
  agent_handoff_origin_unsupported: {
41
41
  summary: "The dashboard origin this deployment is configured with cannot mint canonical agent handoff links.",
42
- fix: "Point SPACEFAST_DASHBOARD_URL at a valid HTTP(S) origin. If you cannot change it, contact support.",
42
+ fix: "Point SPACEFAST_DASHBOARD_URL at a valid HTTP or HTTPS origin. If you cannot change it, contact support.",
43
43
  },
44
44
  ambiguous_space_slug: {
45
45
  summary: "The slug matches spaces in more than one of your teams, so it cannot be resolved.",
@@ -54,8 +54,8 @@ export const ERROR_DOCS = {
54
54
  fix: "Wait for the window to pass, or sign in with an API key for higher limits.",
55
55
  },
56
56
  anonymous_space_limit_reached: {
57
- summary: "This client already holds the maximum number of unclaimed Spaces.",
58
- fix: "Sign in and publish into your account, or claim or delete one of the unclaimed Spaces you already have.",
57
+ summary: "This client already holds the maximum number of unclaimed spaces.",
58
+ fix: "Sign in and publish into your account, or claim or delete one of the unclaimed spaces you already have.",
59
59
  },
60
60
  api_key_scope_underivable: {
61
61
  summary: "A concrete access policy cannot be derived from the requested scope and permissions.",
@@ -79,7 +79,7 @@ export const ERROR_DOCS = {
79
79
  },
80
80
  build_execution_unavailable: {
81
81
  summary: "Build execution is not available on this deployment.",
82
- fix: "Publish prebuilt static output instead, or wait for builds to become available.",
82
+ fix: "Publish prebuilt output instead.",
83
83
  },
84
84
  build_failed: {
85
85
  summary: "The build run failed before producing a version.",
@@ -101,6 +101,10 @@ export const ERROR_DOCS = {
101
101
  summary: "The build process was killed, most likely after running out of memory.",
102
102
  fix: "Reduce the build's memory usage or concurrency, then start a new build.",
103
103
  },
104
+ build_output_contains_server_bundle: {
105
+ summary: "The build output contains a compiled server bundle (an OpenNext worker.js), which a file-only publish would expose as a public download.",
106
+ fix: "This app needs the Spacefast Functions pipeline: run `sf publish` in the project with the Spacefast CLI so the worker deploys as a Function, or point the output directory at a browser-ready export.",
107
+ },
104
108
  build_output_dir_missing: {
105
109
  summary: "The build finished but its output directory was not produced.",
106
110
  fix: "Point the output directory setting at the folder your build writes (for example dist, build, out, or public).",
@@ -111,7 +115,7 @@ export const ERROR_DOCS = {
111
115
  },
112
116
  blob_gate_record_missing: {
113
117
  summary: "The file behind this download link no longer exists.",
114
- fix: "Ask the owner for a fresh link; the underlying object was deleted.",
118
+ fix: "The underlying object was deleted. Ask the owner for a fresh link.",
115
119
  },
116
120
  blob_gate_token_invalid: {
117
121
  summary: "The download token is invalid or expired.",
@@ -139,7 +143,7 @@ export const ERROR_DOCS = {
139
143
  },
140
144
  claim_blocked_takedown: {
141
145
  summary: "This space is under an abuse takedown and cannot be claimed.",
142
- fix: "Contact support if you believe the takedown is a mistake.",
146
+ fix: "If you believe the takedown is a mistake, contact support.",
143
147
  },
144
148
  claim_target_not_found: {
145
149
  summary: "The team or account to claim the space into was not found.",
@@ -147,7 +151,7 @@ export const ERROR_DOCS = {
147
151
  },
148
152
  claimed_space_quota_exceeded: {
149
153
  summary: "Claiming this space would exceed the target team's space quota.",
150
- fix: "Delete unused spaces, then claim again. Still stuck? POST /v1/feedback with the error code and request id.",
154
+ fix: "Delete unused spaces, then claim again. If you are still stuck, POST /v1/feedback with the error code and requestId.",
151
155
  },
152
156
  cli_upgrade_required: {
153
157
  summary: "This CLI version is too old to talk to the API safely.",
@@ -155,7 +159,7 @@ export const ERROR_DOCS = {
155
159
  },
156
160
  config_file_too_large: {
157
161
  summary: "The sf.jsonc configuration file exceeds the maximum size.",
158
- fix: "Keep the configuration file under the documented size limit (256 KB).",
162
+ fix: "Keep the configuration file at or under 256 KB.",
159
163
  },
160
164
  config_functions_key_removed: {
161
165
  summary: "The sf.jsonc configuration still uses the removed top-level functions key.",
@@ -175,7 +179,7 @@ export const ERROR_DOCS = {
175
179
  },
176
180
  config_runtime_entry_missing: {
177
181
  summary: "The declared runtime has no entry module to compile.",
178
- fix: "Name the entry in sf.jsonc: runtime.entry for functions, runtime.server and runtime.client for zero. Remove the runtime block to publish static files instead.",
182
+ fix: "Name the entry in sf.jsonc: runtime.entry for functions, runtime.server and runtime.client for zero. Remove the runtime block to publish files without a runtime instead.",
179
183
  },
180
184
  config_runtime_invalid_kind: {
181
185
  summary: "The runtime block in the space configuration declares an unknown kind.",
@@ -183,11 +187,11 @@ export const ERROR_DOCS = {
183
187
  },
184
188
  config_templates_over_limit: {
185
189
  summary: "The configuration declares more template files than the plan allows.",
186
- fix: "Reduce the number of template entries in sf.jsonc. Still stuck? POST /v1/feedback with the error code and request id.",
190
+ fix: "Reduce the number of template entries in sf.jsonc. If you are still stuck, POST /v1/feedback with the error code and requestId.",
187
191
  },
188
192
  continuation_unavailable: {
189
193
  summary: "This space key can no longer be exchanged for an API key.",
190
- fix: "If the space is claimed, ask its owner for an API key (dashboard: Account → API keys). If it is still unclaimed, keep using the space key as bearer auth instead of exchanging it. Still stuck? POST /v1/feedback with the error code and request id.",
194
+ fix: "If the space is claimed, ask its owner for an API key (dashboard: Account → API keys). If it is still unclaimed, keep using the space key as bearer auth instead of exchanging it. If you are still stuck, POST /v1/feedback with the error code and requestId.",
191
195
  },
192
196
  continuation_used: {
193
197
  summary: "This space key was already exchanged for a durable API key.",
@@ -199,7 +203,7 @@ export const ERROR_DOCS = {
199
203
  },
200
204
  credential_not_yet_valid: {
201
205
  summary: "The credential is not valid yet because its start time is in the future.",
202
- fix: "Wait until the credential's notBefore time, or adjust it.",
206
+ fix: "Wait until the credential's notBefore time, or adjust the notBefore value.",
203
207
  },
204
208
  credential_retired: {
205
209
  summary: "This request used a retired Spacefast token format or authentication header.",
@@ -231,7 +235,7 @@ export const ERROR_DOCS = {
231
235
  },
232
236
  device_verification_rate_limited: {
233
237
  summary: "Too many incorrect device codes were entered in a short window.",
234
- fix: "Wait for the lockout to pass, then enter the code shown by your CLI exactly.",
238
+ fix: "Wait for the lockout to pass, then enter the code exactly as your CLI shows it.",
235
239
  },
236
240
  dns_export_required: {
237
241
  summary: "This operation requires exporting the current DNS records first.",
@@ -243,7 +247,7 @@ export const ERROR_DOCS = {
243
247
  },
244
248
  dns_import_partial_visibility: {
245
249
  summary: "The DNS import cannot see the full zone, so importing would lose records.",
246
- fix: "Verify delegation and retry once the full zone is visible.",
250
+ fix: "Verify delegation. Once the full zone is visible, retry the import.",
247
251
  },
248
252
  dns_provider_auth_expired: {
249
253
  summary: "The connected DNS provider authorization expired or was revoked.",
@@ -251,7 +255,7 @@ export const ERROR_DOCS = {
251
255
  },
252
256
  dns_provider_batch_unsupported: {
253
257
  summary: "The connected DNS provider cannot apply this batch with the required semantics.",
254
- fix: "Split the change or use a provider/zone that supports atomic batch writes.",
258
+ fix: "Split the change, or use a provider or zone that supports atomic batch writes.",
255
259
  },
256
260
  dns_provider_change_pending: {
257
261
  summary: "The DNS provider accepted the change but propagation or provider completion is still pending.",
@@ -323,7 +327,7 @@ export const ERROR_DOCS = {
323
327
  },
324
328
  dns_provider_replace_all_write_strategy: {
325
329
  summary: "This provider applies DNS changes with a replace-all write strategy.",
326
- fix: "Review the full-zone diff carefully so unrelated MX, TXT, CAA, NS, and wildcard records are preserved.",
330
+ fix: "To preserve unrelated MX, TXT, CAA, NS, and wildcard records, review the full-zone diff carefully.",
327
331
  },
328
332
  dns_provider_snapshot_stale: {
329
333
  summary: "The cached DNS provider snapshot is stale.",
@@ -331,7 +335,7 @@ export const ERROR_DOCS = {
331
335
  },
332
336
  dns_provider_snapshot_unavailable: {
333
337
  summary: `${BRAND.productName} cannot cache the latest DNS provider snapshot.`,
334
- fix: "Retry refresh after the cache or provider recovers. Do not edit connected-provider records from stale data.",
338
+ fix: "Retry the refresh after the cache or provider recovers. Do not edit connected-provider records from stale data.",
335
339
  },
336
340
  dns_provider_temporarily_unavailable: {
337
341
  summary: "The DNS provider is rate-limited, degraded, or temporarily unavailable.",
@@ -403,7 +407,7 @@ export const ERROR_DOCS = {
403
407
  },
404
408
  domain_quota_exceeded: {
405
409
  summary: "Adding this domain would exceed the plan's external domain allowance.",
406
- fix: "Remove unused domains. Still stuck? POST /v1/feedback with the error code and request id.",
410
+ fix: "Remove unused domains. If you are still stuck, POST /v1/feedback with the error code and requestId.",
407
411
  },
408
412
  domain_registration_active: {
409
413
  summary: "The domain has an active registration, which blocks this operation.",
@@ -439,7 +443,7 @@ export const ERROR_DOCS = {
439
443
  },
440
444
  enforcement_policy_overlap: {
441
445
  summary: "Enforcement policy severity ranges overlap within a category.",
442
- fix: "Adjust the category ranges so each severity is covered by at most one policy.",
446
+ fix: "Adjust the category ranges so at most one policy covers each severity.",
443
447
  },
444
448
  expired_token: {
445
449
  summary: "The token is expired.",
@@ -447,7 +451,7 @@ export const ERROR_DOCS = {
447
451
  },
448
452
  feature_unavailable: {
449
453
  summary: "This feature is not available on this deployment or plan.",
450
- fix: "Check the feature's availability and try again when it is enabled for your team.",
454
+ fix: "Check the feature's availability. When the feature is enabled for your team, try again.",
451
455
  },
452
456
  files_mode_does_not_support_spa: {
453
457
  summary: "SPA fallback cannot be combined with files-listing mode.",
@@ -459,11 +463,11 @@ export const ERROR_DOCS = {
459
463
  },
460
464
  free_external_proxy_disabled: {
461
465
  summary: "Proxy routes to external upstreams are not available on the Free plan.",
462
- fix: "Remove the proxy rules before publishing. Still stuck? POST /v1/feedback with the error code and request id.",
466
+ fix: "Remove the proxy rules before publishing. If you are still stuck, POST /v1/feedback with the error code and requestId.",
463
467
  },
464
468
  idempotency_conflict_in_progress: {
465
469
  summary: "Another request with the same Idempotency-Key is still in flight.",
466
- fix: "Wait for the original request to finish. Its response will be replayed.",
470
+ fix: "Wait for the original request to finish. The API will replay that request's response.",
467
471
  },
468
472
  idempotency_key_reused: {
469
473
  summary: "The Idempotency-Key was reused with a different request body.",
@@ -475,7 +479,7 @@ export const ERROR_DOCS = {
475
479
  },
476
480
  inject_invalid: {
477
481
  summary: "The inject config key is malformed.",
478
- fix: "Make inject an object whose head/bodyStart/bodyEnd/noscript entries are arrays of up to 16 strings.",
482
+ fix: "Make `inject` an object whose `head`, `bodyStart`, `bodyEnd`, and `noscript` entries are arrays of up to 16 strings.",
479
483
  },
480
484
  inject_snippet_too_large: {
481
485
  summary: "An inject snippet exceeds the per-snippet size limit.",
@@ -483,7 +487,7 @@ export const ERROR_DOCS = {
483
487
  },
484
488
  internal_error: {
485
489
  summary: "Something went wrong on our side.",
486
- fix: "Retry the request. If it persists, contact support with the requestId.",
490
+ fix: "Retry the request. If the error persists, contact support with the requestId.",
487
491
  },
488
492
  invalid_claim_token: {
489
493
  summary: "The space key is invalid or does not match this space.",
@@ -507,7 +511,7 @@ export const ERROR_DOCS = {
507
511
  },
508
512
  invalid_domain_name: {
509
513
  summary: "The domain name is not a valid registrable hostname.",
510
- fix: "Check the spelling and use a fully-qualified domain name.",
514
+ fix: "Check the spelling and use a fully qualified domain name.",
511
515
  },
512
516
  invalid_file_path: {
513
517
  summary: "A file path in the request is not a valid space path.",
@@ -551,7 +555,7 @@ export const ERROR_DOCS = {
551
555
  },
552
556
  invalid_user_code: {
553
557
  summary: "The user code does not match a pending device login.",
554
- fix: "Enter the code exactly as shown by your CLI. Codes expire after a few minutes.",
558
+ fix: "Enter the code exactly as your CLI shows it. Codes expire after a few minutes.",
555
559
  },
556
560
  invalid_version_path: {
557
561
  summary: "A file path in the version is not a valid space path.",
@@ -595,15 +599,15 @@ export const ERROR_DOCS = {
595
599
  },
596
600
  invitation_not_pending: {
597
601
  summary: "The invitation is no longer pending.",
598
- fix: "Create a new invitation if the member still needs to join.",
602
+ fix: "If the member still needs to join, create a new invitation.",
599
603
  },
600
604
  ip_blocked: {
601
605
  summary: "Requests from this IP address are blocked for abuse or policy reasons.",
602
- fix: "Contact support with your IP address if you believe this block is in error.",
606
+ fix: "If you believe this block is a mistake, contact support with your IP address.",
603
607
  },
604
608
  job_not_found: {
605
609
  summary: "The background job was not found.",
606
- fix: "Verify the job id. Completed jobs are eventually pruned.",
610
+ fix: "Verify the job id. Spacefast eventually prunes completed jobs.",
607
611
  },
608
612
  job_not_promotable: {
609
613
  summary: "The job cannot be promoted in its current state.",
@@ -635,11 +639,11 @@ export const ERROR_DOCS = {
635
639
  },
636
640
  malware_detected: {
637
641
  summary: "Malware was detected in the uploaded content.",
638
- fix: "Remove the flagged files. Contact support if you believe this is a false positive.",
642
+ fix: "Remove the flagged files. If you believe the detection is a false positive, contact support.",
639
643
  },
640
644
  managed_domain_protected: {
641
645
  summary: "This is a system-managed view.fast hostname and cannot be mutated like a custom domain.",
642
- fix: "Use it as a read-only managed hostname, or add a custom domain if you need editable DNS and binding controls.",
646
+ fix: "Use the hostname as a read-only managed hostname. If you need editable DNS and binding controls, add a custom domain.",
643
647
  },
644
648
  manifest_body_too_large: {
645
649
  summary: "The upload manifest body exceeds the maximum size.",
@@ -647,7 +651,7 @@ export const ERROR_DOCS = {
647
651
  },
648
652
  manifest_duplicate_path: {
649
653
  summary: "The upload manifest declares the same path more than once.",
650
- fix: "Deduplicate paths. Comparisons use the canonical (decoded, NFC) form.",
654
+ fix: "Deduplicate paths. Comparisons use the canonical form: decoded and NFC-normalized.",
651
655
  },
652
656
  manifest_too_many_files: {
653
657
  summary: "The upload manifest declares more files than the allowed ceiling.",
@@ -667,15 +671,15 @@ export const ERROR_DOCS = {
667
671
  },
668
672
  move_target_capacity_lost: {
669
673
  summary: "The selected move target no longer has capacity for the space.",
670
- fix: "Retry the move with a different target or after capacity is freed.",
674
+ fix: "Retry the move with a different target, or retry after capacity is freed.",
671
675
  },
672
676
  name_managed_by_config: {
673
677
  summary: "The space name is managed by sf.jsonc while its live version declares one.",
674
- fix: "Change name in sf.jsonc and publish, or remove name from the file to rename the space through the API.",
678
+ fix: "Change `name` in `sf.jsonc` and publish, or remove `name` from the file to rename the space through the API.",
675
679
  },
676
680
  nameserver_delegation_required: {
677
681
  summary: `This operation requires the domain to be delegated to ${BRAND.productName} nameservers.`,
678
- fix: "Update the domain's nameservers at the registrar, then retry once delegation propagates.",
682
+ fix: "Update the domain's nameservers at the registrar. After delegation propagates, retry.",
679
683
  },
680
684
  nameserver_divergence: {
681
685
  summary: "The domain's observed nameservers diverge from the expected set.",
@@ -683,7 +687,7 @@ export const ERROR_DOCS = {
683
687
  },
684
688
  noop_publish: {
685
689
  summary: "The publish matched the live version exactly, so nothing changed.",
686
- fix: "No action needed. The existing live version already serves this content.",
690
+ fix: "No action is needed. The existing live version already serves this content.",
687
691
  },
688
692
  not_enrolled: {
689
693
  summary: "This account is not enrolled in the private beta, so the API cannot be used yet.",
@@ -691,11 +695,11 @@ export const ERROR_DOCS = {
691
695
  },
692
696
  not_found: {
693
697
  summary: "The requested resource was not found.",
694
- fix: "Verify the id and that your credential can access the resource.",
698
+ fix: "Verify that the id is correct and that your credential can access the resource.",
695
699
  },
696
700
  path_case_collision: {
697
701
  summary: "Two file paths differ only by letter case, which collides on serving.",
698
- fix: "Rename one of the files so paths are unique case-insensitively.",
702
+ fix: "Rename one of the files so that paths are unique case-insensitively.",
699
703
  },
700
704
  path_too_long: {
701
705
  summary: "A file path exceeds the maximum length.",
@@ -707,11 +711,11 @@ export const ERROR_DOCS = {
707
711
  },
708
712
  plan_grant_already_revoked: {
709
713
  summary: "This plan grant was already revoked.",
710
- fix: "Nothing to do. Create a new grant if the team should regain the plan.",
714
+ fix: "No action is needed. If the team should regain the plan, create a new grant.",
711
715
  },
712
716
  placement_invalid_burstable: {
713
717
  summary: "The placement burstable option was used with an unsupported placement mode.",
714
- fix: 'Set placement.mode to "dedicated" before setting placement.burstable, or remove the burstable option.',
718
+ fix: 'Set `placement.mode` to `"dedicated"` before setting `placement.burstable`, or remove the burstable option.',
715
719
  },
716
720
  platform_tenant_immutable_client: {
717
721
  summary: "The tenant's provider client cannot be changed.",
@@ -721,9 +725,13 @@ export const ERROR_DOCS = {
721
725
  summary: "The requested key policy grants more than your own credential allows.",
722
726
  fix: "Request a policy that is a subset of the credential creating the key.",
723
727
  },
728
+ prebuilt_metadata_invalid: {
729
+ summary: "The metadata file next to the prebuilt archive exists but cannot be read or parsed, so the build's runtime shape is unknown.",
730
+ fix: "Re-run `sf build` to regenerate the archive and its metadata together. If the archive contains plain files, delete the metadata file.",
731
+ },
724
732
  ingest_admission_exceeded: {
725
733
  summary: "Too many concurrent uploads for this space.",
726
- fix: "Wait for the Retry-After window, then resume; at most 4 uploads run per space at once.",
734
+ fix: "Wait for the Retry-After window, then resume. At most 4 uploads run per space at once.",
727
735
  },
728
736
  principal_space_mismatch: {
729
737
  summary: "The space does not belong to the principal in the request.",
@@ -731,11 +739,11 @@ export const ERROR_DOCS = {
731
739
  },
732
740
  promote_admission_exceeded: {
733
741
  summary: "Too many archived files are being restored for this space right now.",
734
- fix: "Retry shortly; restores are limited to protect the host.",
742
+ fix: "Retry shortly. Spacefast limits restores to protect the host.",
735
743
  },
736
744
  provider_error: {
737
- summary: "The hosting provider reported an error.",
738
- fix: "Retry. If the error persists, contact support with the requestId.",
745
+ summary: "WP Cloud reported an error.",
746
+ fix: "Retry. If the error persists, contact support with the `requestId`.",
739
747
  },
740
748
  provider_job_failed: {
741
749
  summary: "A hosting-provider job failed while processing this operation.",
@@ -743,35 +751,35 @@ export const ERROR_DOCS = {
743
751
  },
744
752
  provider_job_timeout: {
745
753
  summary: "A hosting-provider job timed out while processing this operation.",
746
- fix: "Retry the operation. If the provider is slow right now, wait and retry again.",
754
+ fix: "Retry the operation. If the provider is slow, wait and retry again.",
747
755
  },
748
756
  provider_privilege: {
749
- summary: "The hosting provider does not grant this client permission to change the setting.",
757
+ summary: "WP Cloud does not grant this client permission to change the setting.",
750
758
  fix: "Leave the provider-owned setting unchanged or contact support to request the required provider capability.",
751
759
  },
752
760
  provider_runtime_feature_unsupported: {
753
- summary: "The hosting provider does not support this runtime feature.",
761
+ summary: "WP Cloud does not support this runtime feature.",
754
762
  fix: "Check the feature's availability for this site's runtime.",
755
763
  },
756
764
  provider_site_id_required: {
757
765
  summary: "A provider site id is required for this internal operation.",
758
- fix: "Pass the provider site reference.",
766
+ fix: "Pass the provider site id.",
759
767
  },
760
768
  proxy_upstream_denied: {
761
769
  summary: "The proxy upstream is on a denied network and cannot be used.",
762
- fix: "Proxy only to public HTTPS upstreams. Private and internal addresses are blocked.",
770
+ fix: "Proxy only to public HTTPS upstreams. Spacefast blocks private and internal addresses.",
763
771
  },
764
772
  proxy_upstream_unresolved: {
765
773
  summary: "The proxy upstream hostname cannot be resolved.",
766
- fix: "Verify the upstream DNS name resolves publicly, then publish again.",
774
+ fix: "Verify that the upstream DNS name resolves publicly, then publish again.",
767
775
  },
768
776
  publish_session_expired: {
769
777
  summary: "This publish session expired before it was finalized.",
770
- fix: "Start a new publish; declared uploads are kept for 24 hours only.",
778
+ fix: "Start a new publish. Spacefast keeps declared uploads for 24 hours only.",
771
779
  },
772
780
  publish_archive_compression_ratio_exceeded: {
773
781
  summary: "The archive's compression ratio is suspiciously high and was rejected.",
774
- fix: "Repackage the content without highly-compressible filler data.",
782
+ fix: "Repackage the content without highly compressible filler data.",
775
783
  },
776
784
  publish_archive_expanded_size_exceeded: {
777
785
  summary: "The archive expands beyond the maximum allowed total size.",
@@ -787,7 +795,7 @@ export const ERROR_DOCS = {
787
795
  },
788
796
  publish_base_changed: {
789
797
  summary: "Someone published new space settings after the base you loaded, so saving would overwrite their change.",
790
- fix: "Reload the latest settings, review the difference, and save again. Pass force only to overwrite deliberately.",
798
+ fix: "Reload the latest settings, review the difference, and save again. Pass `force` only to overwrite deliberately.",
791
799
  },
792
800
  publish_bytes_missing: {
793
801
  summary: "The publish has no complete staged content to materialize.",
@@ -795,7 +803,7 @@ export const ERROR_DOCS = {
795
803
  },
796
804
  publish_config_unsupported: {
797
805
  summary: "The publish carries configuration this endpoint does not support.",
798
- fix: "Move the configuration into sf.jsonc or the space settings.",
806
+ fix: "Move the configuration into `sf.jsonc` or the space settings.",
799
807
  },
800
808
  publish_failed: {
801
809
  summary: "The publish failed before going live.",
@@ -815,11 +823,11 @@ export const ERROR_DOCS = {
815
823
  },
816
824
  publish_not_cancelable: {
817
825
  summary: "The publish is past the point where it can be canceled.",
818
- fix: "Wait for the publish to finish, then roll back by promoting a previous version if needed.",
826
+ fix: "Wait for the publish to finish. To roll back, promote a previous version.",
819
827
  },
820
828
  publish_path_collision: {
821
829
  summary: "Two different artifacts would serve the same URL after directory-index or clean-URL resolution.",
822
- fix: "Rename or remove one artifact so every request route has one owner.",
830
+ fix: "Rename or remove one artifact so that every request route has one owner.",
823
831
  },
824
832
  publish_path_invalid: {
825
833
  summary: "A publish path is not a relative, normalized POSIX path.",
@@ -827,7 +835,7 @@ export const ERROR_DOCS = {
827
835
  },
828
836
  publish_setup_failed: {
829
837
  summary: "Provisioning for this publish failed.",
830
- fix: "Retry the publish. If it persists, contact support with the requestId.",
838
+ fix: "Retry the publish. If the error persists, contact support with the `requestId`.",
831
839
  },
832
840
  publish_snapshot_empty: {
833
841
  summary: "An empty snapshot was sent without an explicit base version.",
@@ -851,7 +859,7 @@ export const ERROR_DOCS = {
851
859
  },
852
860
  response_table_too_large: {
853
861
  summary: "A compiled response table exceeded the 1 MiB per-file limit.",
854
- fix: "This version has an unusually dense path set; contact support with the requestId.",
862
+ fix: "This version has an unusually dense path set. Contact support with the `requestId`.",
855
863
  },
856
864
  rate_limited: {
857
865
  summary: "Too many requests were made in a short window.",
@@ -867,15 +875,15 @@ export const ERROR_DOCS = {
867
875
  },
868
876
  resource_revision_changed: {
869
877
  summary: "The resource changed after you loaded it, so the stale write was rejected.",
870
- fix: "Use the current resource returned in error.details.current, reapply the intended fields, and send its revision as expectedRevision.",
878
+ fix: "Use the current resource returned in `error.details.current`, reapply the intended fields, and send its revision as `expectedRevision`.",
871
879
  },
872
880
  review_item_claimed: {
873
881
  summary: "Another reviewer already claimed this review item.",
874
- fix: "Pick a different item, or ask the current assignee (error.details.assignedToUserId) to release it.",
882
+ fix: "Pick a different item, or ask the current assignee to release it. The assignee's id is in `error.details.assignedToUserId`.",
875
883
  },
876
884
  routing_rules_over_plan: {
877
885
  summary: "The published _redirects and _headers exceed the plan's routing-rule allowance.",
878
- fix: "Reduce the rule count. Still stuck? POST /v1/feedback with the error code and request id.",
886
+ fix: "Reduce the rule count. If you still need more rules, POST to `/v1/feedback` with the error code and the `requestId`.",
879
887
  },
880
888
  runtime_action_forbidden: {
881
889
  summary: "The runtime credential does not allow this action.",
@@ -883,7 +891,7 @@ export const ERROR_DOCS = {
883
891
  },
884
892
  runtime_api_not_found: {
885
893
  summary: "The runtime management endpoint was not found.",
886
- fix: "Send the request with the management hostname as the Host header. Management routes are not served on public hostnames.",
894
+ fix: "Send the request with the management hostname as the Host header. Spacefast does not serve management routes on public hostnames.",
887
895
  },
888
896
  runtime_callback_forbidden: {
889
897
  summary: "The runtime callback cannot be authenticated.",
@@ -891,19 +899,19 @@ export const ERROR_DOCS = {
891
899
  },
892
900
  runtime_dev_unsupported: {
893
901
  summary: "`sf dev` cannot run this runtime locally yet.",
894
- fix: "Run your framework's own dev server (`next dev`, `vite`, …) and publish with `sf publish` when you are ready.",
902
+ fix: "Run your framework's own dev server, such as `next dev` or `vite`. When you are ready, publish with `sf publish`.",
895
903
  },
896
904
  runtime_hostname_unassigned: {
897
905
  summary: "The hostname is not assigned to a runtime, so the request cannot be routed.",
898
- fix: `Verify the binding is active and DNS points at ${BRAND.productName}.`,
906
+ fix: `Verify that the binding is active and that DNS points at ${BRAND.productName}.`,
899
907
  },
900
908
  runtime_instance_mismatch: {
901
909
  summary: "The request reached a different runtime instance than the one it was issued for.",
902
- fix: "Re-request instructions. The space is on another instance now.",
910
+ fix: "Re-request instructions. The space is on another instance.",
903
911
  },
904
912
  runtime_jti_missing: {
905
913
  summary: "The runtime token is missing its replay-protection id.",
906
- fix: "Mint a fresh runtime token. Tokens must carry a jti claim.",
914
+ fix: "Mint a fresh runtime token. Tokens must carry a `jti` claim.",
907
915
  },
908
916
  runtime_jti_replayed: {
909
917
  summary: "The runtime token was already used. Replays are rejected.",
@@ -915,7 +923,7 @@ export const ERROR_DOCS = {
915
923
  },
916
924
  runtime_kind_mismatch: {
917
925
  summary: "This operation is only available for a different runtime kind.",
918
- fix: "Check `sf runtime status` for what the live version actually runs, then use the surface that runtime supports.",
926
+ fix: "Check `sf runtime status` for what the live version actually runs, then use the operations that runtime supports.",
919
927
  },
920
928
  runtime_management_unavailable: {
921
929
  summary: "The runtime management surface is unavailable for this site.",
@@ -923,7 +931,7 @@ export const ERROR_DOCS = {
923
931
  },
924
932
  runtime_not_provisioned: {
925
933
  summary: "The space does not serve a published version yet, so it has no runtime data to read.",
926
- fix: "Publish a version first. If a publish is already running, wait for it the operation receipt reports progress.",
934
+ fix: "Publish a version first. If a publish is already running, wait for it. The operation receipt reports progress.",
927
935
  },
928
936
  runtime_operation_missing: {
929
937
  summary: "The runtime operation referenced by this request was not found.",
@@ -931,7 +939,11 @@ export const ERROR_DOCS = {
931
939
  },
932
940
  runtime_purge_failed: {
933
941
  summary: "Content updated but the edge cache purge did not confirm.",
934
- fix: "The runtime retries automatically; recent visitors may briefly see the previous version.",
942
+ fix: "The runtime retries automatically. Recent visitors may briefly see the previous version.",
943
+ },
944
+ runtime_release_unverifiable: {
945
+ summary: "The requested platform release could not be verified at its origin.",
946
+ fix: "Check that the release exists and published its full set of artifacts, then request it again.",
935
947
  },
936
948
  runtime_scope_forbidden: {
937
949
  summary: "The runtime token's scope does not cover this path or action.",
@@ -939,7 +951,7 @@ export const ERROR_DOCS = {
939
951
  },
940
952
  runtime_token_bad_signature: {
941
953
  summary: "The runtime token signature did not verify.",
942
- fix: "Mint a fresh token. Verify clocks and JWKS freshness if it persists.",
954
+ fix: "Mint a fresh runtime token. If the error persists, verify clocks and JWKS freshness.",
943
955
  },
944
956
  runtime_token_expired: {
945
957
  summary: "The runtime token is expired.",
@@ -951,7 +963,7 @@ export const ERROR_DOCS = {
951
963
  },
952
964
  runtime_unauthorized: {
953
965
  summary: "The request to the runtime carried no valid credential.",
954
- fix: "Send the runtime JWT in the Authorization header.",
966
+ fix: "Send the runtime token in the Authorization header.",
955
967
  },
956
968
  runtime_upload_operation_not_supported: {
957
969
  summary: "The runtime upload session does not support this operation.",
@@ -963,7 +975,7 @@ export const ERROR_DOCS = {
963
975
  },
964
976
  scan_pending: {
965
977
  summary: "The content is still being scanned for safety and cannot be served yet.",
966
- fix: "Wait for the scan to finish. Serving resumes automatically once it clears.",
978
+ fix: "Wait for the scan to finish. Serving resumes automatically once the scan clears.",
967
979
  },
968
980
  secret_variable_in_template: {
969
981
  summary: "A secret variable was referenced in a template, which is blocked.",
@@ -971,7 +983,7 @@ export const ERROR_DOCS = {
971
983
  },
972
984
  service_booting: {
973
985
  summary: "The process that received this request is still starting and cannot serve it yet.",
974
- fix: "Wait for the Retry-After window, then send the same request again.",
986
+ fix: "Wait for the `Retry-After` window, then send the same request again.",
975
987
  },
976
988
  service_signature_invalid: {
977
989
  summary: "The service request signature cannot be verified.",
@@ -979,7 +991,7 @@ export const ERROR_DOCS = {
979
991
  },
980
992
  site_already_deleted: {
981
993
  summary: "The site was already deleted.",
982
- fix: "No action needed. The site is gone.",
994
+ fix: "No action is needed. The site is gone.",
983
995
  },
984
996
  site_has_live_spaces: {
985
997
  summary: "The site still has live spaces assigned to it, so it cannot be deleted.",
@@ -1027,7 +1039,7 @@ export const ERROR_DOCS = {
1027
1039
  },
1028
1040
  space_already_claimed: {
1029
1041
  summary: "The space was already claimed. A claim can only succeed once.",
1030
- fix: "If you published this space, exchange your space key once at POST /v1/claim/exchange. Keep publishing to the same spaceId with that durable API key. Otherwise ask the owner for access do not publish a duplicate space.",
1042
+ fix: "If you published this space, exchange your space key once at `POST /v1/claim/exchange`. Keep publishing to the same `spaceId` with that durable API key. Otherwise ask the owner for access. Do not publish a duplicate space.",
1031
1043
  },
1032
1044
  space_claim_unavailable: {
1033
1045
  summary: "This space cannot be claimed.",
@@ -1035,15 +1047,15 @@ export const ERROR_DOCS = {
1035
1047
  },
1036
1048
  space_claimed_credential_available: {
1037
1049
  summary: "The space was claimed and its owner kept agent publishing enabled; this space key now works exactly once as an exchange voucher.",
1038
- fix: "POST /v1/claim/exchange with this space key as bearer auth. Save the returned API key (e.g. .spacefast/state.json), then retry the request with it as Authorization: Bearer. Do not publish a new space.",
1050
+ fix: "`POST /v1/claim/exchange` with this space key as bearer auth. Save the returned API key (for example in `.spacefast/state.json`), then retry the request with that key as `Authorization: Bearer`. Do not publish a new space.",
1039
1051
  },
1040
1052
  space_disabled: {
1041
1053
  summary: "The space is disabled and cannot be served or modified.",
1042
- fix: "Check the disabled reason on the space. It explains the path to restore it.",
1054
+ fix: "Check the disabled reason on the space. The reason explains how to restore the space.",
1043
1055
  },
1044
1056
  space_expired: {
1045
1057
  summary: "The space expired and is no longer served.",
1046
- fix: "If it is within the recovery window, claim or restore it. Otherwise publish again.",
1058
+ fix: "If the space is within the recovery window, claim or restore it. Otherwise publish again.",
1047
1059
  },
1048
1060
  space_has_active_publish: {
1049
1061
  summary: "The space has a publish in progress, which blocks this operation.",
@@ -1063,7 +1075,7 @@ export const ERROR_DOCS = {
1063
1075
  },
1064
1076
  space_not_disabled: {
1065
1077
  summary: "The space is not disabled, so it cannot be restored.",
1066
- fix: "No action needed. The space is already active.",
1078
+ fix: "No action is needed. The space is already active.",
1067
1079
  },
1068
1080
  space_not_restorable: {
1069
1081
  summary: "The space is past its recovery window and cannot be restored.",
@@ -1083,11 +1095,11 @@ export const ERROR_DOCS = {
1083
1095
  },
1084
1096
  space_ref_ambiguous: {
1085
1097
  summary: "The space reference matches more than one accessible space.",
1086
- fix: "Use the spc_ id, or scope the reference with a teamRef.",
1098
+ fix: "Use the `spc_` id, or scope the reference with a `teamRef`.",
1087
1099
  },
1088
1100
  space_ref_required: {
1089
1101
  summary: "A space reference is required for this operation.",
1090
- fix: "Pass a spc_ id, slug, or hostname.",
1102
+ fix: "Pass a `spc_` id, slug, or hostname.",
1091
1103
  },
1092
1104
  space_transferring: {
1093
1105
  summary: "The space has a transfer in progress, which blocks this operation.",
@@ -1139,7 +1151,7 @@ export const ERROR_DOCS = {
1139
1151
  },
1140
1152
  storage_key_invalid: {
1141
1153
  summary: "The storage object id is malformed.",
1142
- fix: "Use the 32-character object id returned by storage.upload.",
1154
+ fix: "Use the 32-character object id returned by `storage.upload`.",
1143
1155
  },
1144
1156
  storage_object_not_found: {
1145
1157
  summary: "The requested storage object does not exist.",
@@ -1159,15 +1171,15 @@ export const ERROR_DOCS = {
1159
1171
  },
1160
1172
  storage_unavailable: {
1161
1173
  summary: "The runtime cannot read or persist object storage.",
1162
- fix: "Retry on a healthy runtime. Contact support if the failure persists.",
1174
+ fix: "Retry on a healthy runtime. If the failure persists, contact support.",
1163
1175
  },
1164
1176
  stripe_error: {
1165
1177
  summary: "The billing provider reported an error.",
1166
- fix: "Retry. If it persists, check the team's billing settings.",
1178
+ fix: "Retry. If the error persists, check the team's billing settings.",
1167
1179
  },
1168
1180
  superseded_by_publish: {
1169
1181
  summary: "A newer publish superseded this operation, so it was skipped.",
1170
- fix: "No action needed. The newer publish already carries the change.",
1182
+ fix: "No action is needed. The newer publish already carries the change.",
1171
1183
  },
1172
1184
  takeover_notice_window: {
1173
1185
  summary: "The hostname was recently bound elsewhere. A takeover notice window applies.",
@@ -1199,11 +1211,11 @@ export const ERROR_DOCS = {
1199
1211
  },
1200
1212
  template_file_too_large: {
1201
1213
  summary: "A template file exceeds the maximum size for substitution.",
1202
- fix: "Keep template files under the documented size limit (16 KB).",
1214
+ fix: "Keep template files at or under 16 KB.",
1203
1215
  },
1204
1216
  template_not_in_version: {
1205
1217
  summary: "The configuration names a template file the version does not contain.",
1206
- fix: "Upload the file or remove its templates entry from sf.jsonc.",
1218
+ fix: "Upload the file or remove its `templates` entry from `sf.jsonc`.",
1207
1219
  },
1208
1220
  template_variable_unresolved: {
1209
1221
  summary: "A template references a variable that has no value.",
@@ -1235,7 +1247,7 @@ export const ERROR_DOCS = {
1235
1247
  },
1236
1248
  theme_value_invalid: {
1237
1249
  summary: "A theme value in the configuration is outside the allowed grammar.",
1238
- fix: "Use allowed CSS values. The offending key is dropped with a warning otherwise.",
1250
+ fix: "Use allowed CSS values. Otherwise the offending key is dropped with a warning.",
1239
1251
  },
1240
1252
  transfer_cross_tenant_unsupported: {
1241
1253
  summary: "Spaces cannot be transferred across tenants.",
@@ -1247,7 +1259,7 @@ export const ERROR_DOCS = {
1247
1259
  },
1248
1260
  transfer_push_failed: {
1249
1261
  summary: "The source runtime cannot push the space blobs into the transfer bucket.",
1250
- fix: "Retry the move. If it persists, check the source runtime and bucket configuration.",
1262
+ fix: "Retry the move. If the failure persists, check the source runtime and bucket configuration.",
1251
1263
  },
1252
1264
  transfer_source_changed: {
1253
1265
  summary: "The space changed since the transfer was created, so it must be re-confirmed.",
@@ -1259,7 +1271,7 @@ export const ERROR_DOCS = {
1259
1271
  },
1260
1272
  transfer_verify_failed: {
1261
1273
  summary: "The target runtime cannot verify transferred blob content.",
1262
- fix: "Retry the move. If it persists, check the target runtime and bucket integrity.",
1274
+ fix: "Retry the move. If the failure persists, check the target runtime and bucket integrity.",
1263
1275
  },
1264
1276
  unauthorized: {
1265
1277
  summary: "The request carried no valid credential.",
@@ -1287,11 +1299,11 @@ export const ERROR_DOCS = {
1287
1299
  },
1288
1300
  user_banned: {
1289
1301
  summary: "This user is banned for a policy or abuse violation and cannot perform this action.",
1290
- fix: "Contact support to appeal the ban if you believe it is a mistake.",
1302
+ fix: "If you believe the ban is a mistake, contact support to appeal it.",
1291
1303
  },
1292
1304
  validation_error: {
1293
1305
  summary: "A request field failed validation.",
1294
- fix: "Fix the field referenced by pointer and details, then retry.",
1306
+ fix: "Fix the field referenced by `pointer` and `details`, then retry.",
1295
1307
  },
1296
1308
  verification_required: {
1297
1309
  summary: "Domain verification is required before this operation.",
@@ -1299,7 +1311,7 @@ export const ERROR_DOCS = {
1299
1311
  },
1300
1312
  version_already_live: {
1301
1313
  summary: "The version is already live on this channel.",
1302
- fix: "No action needed.",
1314
+ fix: "No action is needed.",
1303
1315
  },
1304
1316
  version_artifact_not_found: {
1305
1317
  summary: "The requested version artifact was not found.",
@@ -1343,7 +1355,7 @@ export const ERROR_DOCS = {
1343
1355
  },
1344
1356
  version_in_use: {
1345
1357
  summary: "The version is referenced by one or more channels and cannot be deleted.",
1346
- fix: "Promote another version on those channels first. Details lists them.",
1358
+ fix: "Promote another version on those channels first. The `details` field lists them.",
1347
1359
  },
1348
1360
  version_live: {
1349
1361
  summary: "The version is live and cannot be deleted.",
@@ -1375,7 +1387,7 @@ export const ERROR_DOCS = {
1375
1387
  },
1376
1388
  version_quota_exceeded: {
1377
1389
  summary: "The space is at its version quota.",
1378
- fix: "Delete old versions. Still stuck? POST /v1/feedback with the error code and request id.",
1390
+ fix: "Delete old versions. If the quota error persists, `POST /v1/feedback` with the error code and request id.",
1379
1391
  },
1380
1392
  version_total_bytes_exceeded: {
1381
1393
  summary: "The version exceeds the maximum total size.",
@@ -1395,7 +1407,7 @@ export const ERROR_DOCS = {
1395
1407
  },
1396
1408
  zero_artifact_abi_mismatch: {
1397
1409
  summary: "The Zero endpoint artifact was built for a different runner ABI.",
1398
- fix: `Rebuild and republish the Zero project with the current ${BRAND.productName} CLI and runtime.`,
1410
+ fix: `Rebuild the Zero project with the current ${BRAND.productName} CLI and runtime, then publish it again.`,
1399
1411
  },
1400
1412
  zero_artifact_invalid: {
1401
1413
  summary: "The Zero endpoint artifact is missing required runtime metadata.",
@@ -1415,7 +1427,7 @@ export const ERROR_DOCS = {
1415
1427
  },
1416
1428
  zero_auth_unavailable: {
1417
1429
  summary: "Hosted Zero auth is not configured for this deployment.",
1418
- fix: "Finalize the Zero version with hosted auth URLs or use guest/local auth.",
1430
+ fix: "Finalize the Zero version with hosted auth URLs, or use guest or local auth.",
1419
1431
  },
1420
1432
  zero_blob_key_invalid: {
1421
1433
  summary: "The local Zero blob key is invalid.",
@@ -1435,15 +1447,15 @@ export const ERROR_DOCS = {
1435
1447
  },
1436
1448
  zero_bootstrap_encode_failed: {
1437
1449
  summary: "The Zero runner cannot encode the JavaScript bootstrap data.",
1438
- fix: "Retry with valid request metadata. Report the issue if it persists.",
1450
+ fix: "Retry with valid request metadata. If the issue persists, report it.",
1439
1451
  },
1440
1452
  zero_bytecode_hash_mismatch: {
1441
1453
  summary: "The Zero endpoint bytecode hash does not match its artifact metadata.",
1442
- fix: "Rebuild and republish so bytecode and endpoint metadata are from the same build.",
1454
+ fix: "Rebuild and publish again so bytecode and endpoint metadata are from the same build.",
1443
1455
  },
1444
1456
  zero_bytecode_invalid: {
1445
1457
  summary: "The Zero endpoint bytecode cannot be loaded by QuickJS.",
1446
- fix: "Rebuild the project with the current Zero runner and redeploy.",
1458
+ fix: "Rebuild the project with the current Zero runner and publish again.",
1447
1459
  },
1448
1460
  zero_bytecode_path_invalid: {
1449
1461
  summary: "The Zero endpoint bytecode path is invalid.",
@@ -1455,7 +1467,7 @@ export const ERROR_DOCS = {
1455
1467
  },
1456
1468
  zero_capabilities_encode_failed: {
1457
1469
  summary: "The runtime cannot encode the Zero endpoint capabilities.",
1458
- fix: "Rebuild with valid capability metadata. Report the failure if it persists.",
1470
+ fix: "Rebuild with valid capability metadata. If the failure persists, report it.",
1459
1471
  },
1460
1472
  zero_client_bundle_not_loaded: {
1461
1473
  summary: "The local Zero dev client bundle is not generated or loaded.",
@@ -1463,11 +1475,11 @@ export const ERROR_DOCS = {
1463
1475
  },
1464
1476
  zero_db_connect_failed: {
1465
1477
  summary: "The Zero runner cannot connect to the configured database.",
1466
- fix: "Verify DATABASE_URL or the generated MySQL connection variables and retry.",
1478
+ fix: "Verify `DATABASE_URL` or the generated MySQL connection variables and retry.",
1467
1479
  },
1468
1480
  zero_db_execute_failed: {
1469
1481
  summary: "A Zero database write failed.",
1470
- fix: "Inspect the mutation, schema, and database logs, then retry after fixing the SQL issue.",
1482
+ fix: "Inspect the mutation, schema, and database logs. Fix the SQL issue, then retry.",
1471
1483
  },
1472
1484
  zero_db_export_cursor_invalid: {
1473
1485
  summary: "The local database export cursor is invalid or belongs to another export.",
@@ -1495,7 +1507,7 @@ export const ERROR_DOCS = {
1495
1507
  },
1496
1508
  zero_db_host_install_failed: {
1497
1509
  summary: "The Zero runner cannot install the database host bridge.",
1498
- fix: "Rebuild with a current runner and report the failure if it repeats.",
1510
+ fix: "Rebuild with a current runner. If the failure repeats, report it.",
1499
1511
  },
1500
1512
  zero_db_operation_invalid: {
1501
1513
  summary: "The Zero database bridge received an invalid operation payload.",
@@ -1511,7 +1523,7 @@ export const ERROR_DOCS = {
1511
1523
  },
1512
1524
  zero_db_query_failed: {
1513
1525
  summary: "A Zero database read failed.",
1514
- fix: "Inspect the query, schema, and database logs, then retry after fixing the SQL issue.",
1526
+ fix: "Inspect the query, schema, and database logs. Fix the SQL issue, then retry.",
1515
1527
  },
1516
1528
  zero_db_row_invalid: {
1517
1529
  summary: "A database row cannot be converted into a Zero response value.",
@@ -1527,7 +1539,7 @@ export const ERROR_DOCS = {
1527
1539
  },
1528
1540
  zero_db_transaction_active: {
1529
1541
  summary: "The Zero runner tried to start a database transaction while one was already active.",
1530
- fix: "Rebuild with the current Zero runner and report the failure if it repeats.",
1542
+ fix: "Rebuild with the current Zero runner. If the failure repeats, report it.",
1531
1543
  },
1532
1544
  zero_db_transaction_commit_failed: {
1533
1545
  summary: "The Zero database transaction cannot be committed.",
@@ -1539,7 +1551,7 @@ export const ERROR_DOCS = {
1539
1551
  },
1540
1552
  zero_db_transaction_missing: {
1541
1553
  summary: "The Zero runner tried to finish a database transaction that was not active.",
1542
- fix: "Rebuild with the current Zero runner and report the failure if it repeats.",
1554
+ fix: "Rebuild with the current Zero runner. If the failure repeats, report it.",
1543
1555
  },
1544
1556
  zero_db_transaction_rollback_failed: {
1545
1557
  summary: "The Zero database transaction cannot be rolled back cleanly.",
@@ -1559,11 +1571,11 @@ export const ERROR_DOCS = {
1559
1571
  },
1560
1572
  zero_db_url_invalid: {
1561
1573
  summary: "The Zero database URL is malformed.",
1562
- fix: "Set DATABASE_URL or the generated database variables to a valid MySQL connection URL.",
1574
+ fix: "Set `DATABASE_URL` or the generated database variables to a valid MySQL connection URL.",
1563
1575
  },
1564
1576
  zero_db_url_missing: {
1565
1577
  summary: "No Zero database URL is configured.",
1566
- fix: "Configure DATABASE_URL or finalize the version with database connection variables.",
1578
+ fix: "Configure `DATABASE_URL` or finalize the version with database connection variables.",
1567
1579
  },
1568
1580
  zero_dev_endpoint_failed: {
1569
1581
  summary: "A local Zero dev endpoint failed while handling the request.",
@@ -1571,7 +1583,7 @@ export const ERROR_DOCS = {
1571
1583
  },
1572
1584
  zero_dump_query_invalid: {
1573
1585
  summary: "The Zero database dump query parameters are invalid.",
1574
- fix: "Use valid table, limit, and cursor parameters.",
1586
+ fix: "Use valid `table`, `limit`, and `cursor` parameters.",
1575
1587
  },
1576
1588
  zero_endpoint_compile_failed: {
1577
1589
  summary: "The runtime cannot compile the Zero endpoint bytecode.",
@@ -1591,11 +1603,11 @@ export const ERROR_DOCS = {
1591
1603
  },
1592
1604
  zero_endpoint_index_invalid: {
1593
1605
  summary: "The Zero endpoint index does not contain valid endpoint mappings.",
1594
- fix: "Rebuild and republish the Zero project.",
1606
+ fix: "Rebuild the Zero project and publish it again.",
1595
1607
  },
1596
1608
  zero_endpoint_index_malformed: {
1597
1609
  summary: "The Zero endpoint index cannot be parsed.",
1598
- fix: "Rebuild the generated endpoint index and redeploy.",
1610
+ fix: "Rebuild the generated endpoint index and publish again.",
1599
1611
  },
1600
1612
  zero_endpoint_index_path_invalid: {
1601
1613
  summary: "The Zero endpoint index path is invalid.",
@@ -1603,7 +1615,7 @@ export const ERROR_DOCS = {
1603
1615
  },
1604
1616
  zero_endpoint_index_unreadable: {
1605
1617
  summary: "The Zero endpoint index cannot be read.",
1606
- fix: "Verify the version finalized with zero/endpoints-index.json present.",
1618
+ fix: "Verify the version finalized with `zero/endpoints-index.json` present.",
1607
1619
  },
1608
1620
  zero_endpoint_invalid: {
1609
1621
  summary: "A Zero endpoint definition or its database metadata is invalid.",
@@ -1611,7 +1623,7 @@ export const ERROR_DOCS = {
1611
1623
  },
1612
1624
  zero_endpoint_mismatch: {
1613
1625
  summary: "The requested Zero endpoint does not match the endpoint artifact.",
1614
- fix: "Rebuild routes and artifacts together and redeploy the version.",
1626
+ fix: "Rebuild routes and artifacts together, then publish the version again.",
1615
1627
  },
1616
1628
  zero_endpoint_not_found: {
1617
1629
  summary: "No Zero endpoint artifact exists for this endpoint id.",
@@ -1627,7 +1639,7 @@ export const ERROR_DOCS = {
1627
1639
  },
1628
1640
  zero_envelope_encode_failed: {
1629
1641
  summary: "The PHP bridge cannot encode the Zero runner request envelope.",
1630
- fix: "Retry with valid request data. Report the issue if it persists.",
1642
+ fix: "Retry with valid request data. If the issue persists, report it.",
1631
1643
  },
1632
1644
  zero_js_context_init_failed: {
1633
1645
  summary: "The Zero runner cannot initialize a QuickJS context.",
@@ -1643,11 +1655,11 @@ export const ERROR_DOCS = {
1643
1655
  },
1644
1656
  zero_js_globals_failed: {
1645
1657
  summary: "The Zero runner cannot install runtime globals for the endpoint.",
1646
- fix: "Rebuild with a current runner and report the failure if it repeats.",
1658
+ fix: "Rebuild with a current runner. If the failure repeats, report it.",
1647
1659
  },
1648
1660
  zero_js_response_malformed: {
1649
1661
  summary: "The Zero endpoint returned a malformed runner response.",
1650
- fix: "Return a valid Response or supported Zero handler result.",
1662
+ fix: "Return a valid `Response` or supported Zero handler result.",
1651
1663
  },
1652
1664
  zero_js_runtime_init_failed: {
1653
1665
  summary: "The Zero runner cannot initialize QuickJS.",
@@ -1655,7 +1667,7 @@ export const ERROR_DOCS = {
1655
1667
  },
1656
1668
  zero_log_query_invalid: {
1657
1669
  summary: "The Zero log query parameters are invalid.",
1658
- fix: "Use valid cursor, limit, handlerName, and requestId parameters.",
1670
+ fix: "Pass `cursor` exactly as the previous page's `nextCursor`, keep `limit` between 1 and 100, and send `since` and `until` as ISO timestamps.",
1659
1671
  },
1660
1672
  zero_method_not_allowed: {
1661
1673
  summary: "The request method is not allowed for this Zero endpoint.",
@@ -1667,7 +1679,7 @@ export const ERROR_DOCS = {
1667
1679
  },
1668
1680
  zero_query_name_missing: {
1669
1681
  summary: "A Zero realtime query subscription did not include a query name.",
1670
- fix: "Send a query.subscribe frame with a valid query name.",
1682
+ fix: "Send a `query.subscribe` frame with a valid query name.",
1671
1683
  },
1672
1684
  zero_realtime_forbidden: {
1673
1685
  summary: "The Zero realtime event intake credential is invalid.",
@@ -1679,7 +1691,7 @@ export const ERROR_DOCS = {
1679
1691
  },
1680
1692
  zero_realtime_operation_unsupported: {
1681
1693
  summary: "The Zero realtime websocket operation is unsupported.",
1682
- fix: "Use a supported Zero realtime operation such as query.subscribe or query.unsubscribe.",
1694
+ fix: "Use a supported Zero realtime operation such as `query.subscribe` or `query.unsubscribe`.",
1683
1695
  },
1684
1696
  zero_realtime_query_invalid: {
1685
1697
  summary: "The Zero realtime query subscription payload is invalid.",
@@ -1687,7 +1699,7 @@ export const ERROR_DOCS = {
1687
1699
  },
1688
1700
  zero_realtime_space_required: {
1689
1701
  summary: "The Zero realtime request does not identify a space.",
1690
- fix: "Use a /spaces/{spaceId} realtime URL or include a valid spaceId query parameter.",
1702
+ fix: "Use a `/spaces/{spaceId}` realtime URL or include a valid `spaceId` query parameter.",
1691
1703
  },
1692
1704
  zero_realtime_unavailable: {
1693
1705
  summary: "Zero realtime helpers are unavailable for this endpoint.",
@@ -1699,11 +1711,11 @@ export const ERROR_DOCS = {
1699
1711
  },
1700
1712
  zero_replay_failed: {
1701
1713
  summary: "The hosted Zero runtime cannot fetch realtime replay events.",
1702
- fix: "Retry shortly. Check the central realtime and control-plane logs if it persists.",
1714
+ fix: "Retry shortly. If the failure persists, check the central realtime and control-plane logs.",
1703
1715
  },
1704
1716
  zero_replay_query_invalid: {
1705
1717
  summary: "The hosted Zero realtime replay query is invalid.",
1706
- fix: "Use a valid afterEventId cursor and numeric limit.",
1718
+ fix: "Use a valid `afterEventId` cursor and numeric limit.",
1707
1719
  },
1708
1720
  zero_replay_unavailable: {
1709
1721
  summary: "Realtime replay is not configured for this Zero version.",
@@ -1711,7 +1723,7 @@ export const ERROR_DOCS = {
1711
1723
  },
1712
1724
  zero_request_body_too_large: {
1713
1725
  summary: "The Zero request body exceeds the runtime size limit.",
1714
- fix: "Send a smaller request body or move large payloads to blob/object storage.",
1726
+ fix: "Send a smaller request body or move large payloads to blob or object storage.",
1715
1727
  },
1716
1728
  zero_response_header_forbidden: {
1717
1729
  summary: "A Zero endpoint attempted to set a platform-managed response header.",
@@ -1747,7 +1759,7 @@ export const ERROR_DOCS = {
1747
1759
  },
1748
1760
  zero_runner_envelope_invalid: {
1749
1761
  summary: "The Zero runner request envelope is malformed.",
1750
- fix: "Use the generated runtime bridge and redeploy if generated files are stale.",
1762
+ fix: "Use the generated runtime bridge. If generated files are stale, publish again.",
1751
1763
  },
1752
1764
  zero_runner_failed: {
1753
1765
  summary: "The Zero runner process exited without a valid response.",
@@ -1759,15 +1771,15 @@ export const ERROR_DOCS = {
1759
1771
  },
1760
1772
  zero_runner_invalid_response: {
1761
1773
  summary: "The Zero runner output was not valid JSON.",
1762
- fix: "Inspect runner stderr and rebuild the runner if the failure persists.",
1774
+ fix: "Inspect runner stderr. If the failure persists, rebuild the runner.",
1763
1775
  },
1764
1776
  zero_runner_invalid_status: {
1765
1777
  summary: "The Zero runner returned an invalid HTTP status.",
1766
- fix: "Ensure endpoint handlers return a status between 100 and 599.",
1778
+ fix: "Return a status between 100 and 599 from endpoint handlers.",
1767
1779
  },
1768
1780
  zero_runner_protocol_unsupported: {
1769
1781
  summary: "The Zero runner received an unsupported invoke protocol.",
1770
- fix: "Rebuild and redeploy so the PHP bridge and Rust runner versions match.",
1782
+ fix: "Rebuild and publish again so the PHP bridge and Rust runner versions match.",
1771
1783
  },
1772
1784
  zero_runner_response_encode_failed: {
1773
1785
  summary: "The Zero runner cannot encode its response.",
@@ -1775,7 +1787,7 @@ export const ERROR_DOCS = {
1775
1787
  },
1776
1788
  zero_runner_stdin_invalid: {
1777
1789
  summary: "The Zero runner cannot read its request envelope.",
1778
- fix: "Retry. Report the runtime bridge failure if it persists.",
1790
+ fix: "Retry. If the runtime bridge failure persists, report it.",
1779
1791
  },
1780
1792
  zero_runner_stdin_too_large: {
1781
1793
  summary: "The Zero runner request envelope is too large.",