본문으로 건너뛰기
cccskills
무료GitHub에 공개

fastly-compute-publish-ignores-draft-versions

Fix "backend exists on a draft version but isn't reachable from the new Compute deploy" bugs after `fastly compute publish`. Use when: (1) You ran `fastly service backend create --autoclone` (or any dashboard/CLI change that creates a draft version) but did not activate that draft, (2) You then ran `fastly compute publish` which appeared successful but your backend / ACL / header / dictionary change is missing from the active version, (3) Compute code returns backend-not-found errors or misroutes requests, (4) You're surprised to see your draft version number "skipped over" in the version chain. Root cause: `fastly compute publish` clones from the currently-active version, not from the latest draft, so dashboard changes made in an un-activated draft get stranded.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

설치 방법 보기

포함된 파일(1)

  • SKILL.md9.0 KB

SKILL.md(원문)

설치하기 전에 에이전트에게 전달되는 지시 내용을 확인할 수 있습니다.

fastly compute publish ignores non-active draft versions

Problem

Fastly service versions are immutable. To change a service you clone the active version, edit the clone (a draft), then activate the clone. Multiple tools create drafts:

  • fastly service backend create --autoclone — creates a draft off the active version and adds the backend
  • fastly service domain create --autoclone — same, for domains
  • Dashboard UI "Clone" button
  • fastly compute publish — also creates a draft, uploads WASM, activates

If you mix these tools on the same service you get a surprising footgun: each tool clones from the currently-active version, independently, and each activates its own clone. Draft versions that were never activated are abandoned. Their edits are invisible to whatever the next tool clones from.

Example sequence that bites:

t0  Active = v250
t1  $ fastly service backend create --version latest --autoclone \
       --name cloud_run_transcoder --address ...
    → creates v251 (clone of v250) + adds backend
    → v251 is DRAFT, not active
    → "latest" in this context means "highest version number" (v251), not "active version"

t2  $ fastly compute publish --comment "ship fix"
    → creates v252 (clone of v250, NOT v251) + new WASM
    → stages and activates v253 (clone of v252) + activates
    → v251's backend change was never carried forward
    → active = v253, which does NOT contain cloud_run_transcoder

t3  Compute code at v253 calls send_async("cloud_run_transcoder")
    → backend name does not exist on v253
    → silent failure, fire-and-forget hides it

The naming is misleading: --version latest does not mean "the latest active version," it means "the highest-numbered version," which can be a draft nobody activated. And fastly compute publish never looks at your draft — it clones from whatever is currently active. So your backend change is orphaned in an unreachable draft version, and the active version has the new code but the old backend list.

Context / Trigger Conditions

  • Compute logs show Backend X does not exist or similar after a deploy that "worked"
  • send_async(BACKEND) calls return errors that the code silently swallows (see skill fastly-compute-async-request-reliability)
  • fastly service version list --service-id ID shows a gap or out-of-order creation timestamps — e.g. v251 created at 23:17, v252/v253 created at 23:27, v253 active, but v252 was cloned from v250 not v251
  • fastly service backend list --version N where N is active shows a DIFFERENT backend set from fastly service backend list --version (N-2) where N-2 is the draft you thought you were building on
  • You added a dashboard resource "just before" running fastly compute publish and the publish succeeded but the resource seems to be ignored

Solution

Detection

# Find all versions and which is active
fastly service version list --service-id YOUR_SERVICE_ID

# For each recent version, list backends (or whatever resource you added)
for v in 250 251 252 253 254; do
  echo "=== v$v ==="
  fastly service backend list --service-id YOUR_SERVICE_ID --version $v | grep MY_BACKEND_NAME
done

If the backend appears on a non-active draft (e.g. v251) but is absent from active (e.g. v253), you have this bug.

Fix: add the resource to the currently-active version via --autoclone

# Creates a new draft cloned from the active version, with the backend added.
# Activate the draft atomically afterward.
fastly service backend create --service-id YOUR_SERVICE_ID --version latest --autoclone \
  --name cloud_run_transcoder \
  --address divine-transcoder-149672065768.us-central1.run.app \
  --port 443 --use-ssl \
  --ssl-sni-hostname divine-transcoder-149672065768.us-central1.run.app \
  --override-host divine-transcoder-149672065768.us-central1.run.app

# Confirm the draft has the backend
fastly service backend list --service-id YOUR_SERVICE_ID --version LATEST_DRAFT \
  | grep cloud_run_transcoder

# Activate
fastly service version activate --service-id YOUR_SERVICE_ID --version LATEST_DRAFT

# Purge cache so any poisoned 404/502 responses drop
fastly purge --all --service-id YOUR_SERVICE_ID

Note: --version latest in the backend create command here is safe because after the previous drifted fastly compute publish, the latest draft's parent IS the currently-active version. You're cloning off the right base now.

Prevention (choose one)

  1. Do all non-code changes through fastly compute publish first, then WASM changes. If you ran fastly compute publish without any dashboard/CLI changes queued, the active version gets incremented by 2 (clone → activate) and there are no stranded drafts. Add your backend after the publish via --autoclone, which then creates a fresh draft off the new active version, and activate it.

  2. Always activate your draft before running fastly compute publish. If you ran fastly service backend create --autoclone and got v251, activate v251 before the compute publish. Then compute publish will clone from v251 and carry the backend.

  3. Treat every draft version as an unshipped change. Before any fastly compute publish, run fastly service version list --service-id ID and verify no drafts exist that you intended to ship. If there are drafts you don't want, explicitly abandon them; if there are drafts you do want, activate them first.

  4. Use --verbose on fastly compute publish. The verbose output shows which version number it cloned from. If that number is older than your last draft, you know you've drifted.

Verification

After the fix, confirm:

# Active version has the backend
fastly service backend list --service-id YOUR_SERVICE_ID --version $(fastly service version list --service-id YOUR_SERVICE_ID | awk '$3=="true"{print $1}') | grep MY_BACKEND_NAME

# End-to-end: hit a Compute endpoint that exercises the backend and check logs
# for successful routing (no "backend does not exist" errors)
fastly log tail --service-id YOUR_SERVICE_ID | grep -iE "backend|MY_BACKEND"

For the Divine Blossom example (2026-04-05), the symptom was that PR #59's fix to route transcoder triggers via a new TRANSCODER_BACKEND = "cloud_run_transcoder" constant was deployed in version 253 but the backend itself was stranded in v251. The compute code was silently 404-ing on every send_async to the transcoder. Fix was fastly service backend create --version latest --autoclone → new v254 with both the WASM and the backend → activate v254 → purge.

Notes

  • The same issue applies to any resource you can add with --autoclone: backends, domains, ACLs, dictionaries, edge dictionaries, header rules, VCL snippets (on VCL services), logging endpoints. Anything that creates a draft version is at risk.
  • The fastly compute publish command has no --base-version flag to explicitly say "clone from this version." It always clones from active.
  • VCL services that mix fastly vcl snippet create --autoclone + fastly vcl custom update can hit the same trap.
  • If you have multiple people making changes concurrently, the risk multiplies: one person's draft can be invalidated by another person's publish without either of them noticing.
  • The Fastly CLI does not warn about stranded drafts. They don't expire automatically (AFAIK); they just become zombie versions.
  • Check fastly service version list --service-id ID output carefully — the "active" column tells you which version is live; everything else is a draft or a previous active. Timestamps can be misleading because draft versions carry the timestamp of the fastly service version clone call, not of the content change.

References

  • fastly compute publish source behavior documented in the Fastly CLI repo — see the publish subcommand implementation for the clone-active-and-activate flow
  • Related skill: fastly-compute-async-request-reliability — covers how silently-failing send_async hides this exact bug when the backend goes missing
  • Related skill: fastly-compute-backend-production-setup — covers the "backend exists locally but not in production" sibling bug

리뷰

아직 리뷰가 없습니다. 사용해 본 소감을 남겨 주세요.

댓글

로그인 없이 쓸 수 있습니다. 사용 후기, 질문, 작동하지 않은 환경 등을 편하게 남겨 주세요.

아직 댓글이 없습니다. 첫 댓글을 남겨 보세요.

보내면 바로 공개됩니다. 이메일 주소나 전화번호 같은 개인 정보는 쓰지 마세요. URL은 2개까지입니다.

0 / 1,000자

이 양식은 reCAPTCHA로 보호되며 Google 개인정보처리방침 및 서비스 약관이 적용됩니다.

같은 저장소의 스킬

Fix ArgoCD ExternalSecret deployment failing with "namespace X is not permitted in project Y". Use when: (1) ExternalSecret shows OutOfSync in ArgoCD but won't sync, (2) ArgoCD application status shows "namespace X is not permitted in project 'infrastructure'", (3) ExternalSecret targets a namespace managed by a different ArgoCD project, (4) Using apps-of-apps pattern with separate infrastructure and application projects.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

divinevideo/divine-mobile2652026년 10월 22일 업데이트

Art direction for any content — reads text, PDF, Word, HTML, PPT, then proposes 2-3 creative directions with photography style, mood, and visual language. After selection, generates AI image prompts and visual briefs section-by-section. Use when the user shares content and needs visual direction, image sourcing, or creative direction for any material.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

divinevideo/divine-mobile2652026년 10월 22일 업데이트

Fix "Null check operator used on a null value" errors when an object is set to null during an async await. Use when: (1) Object reference is nullified while awaiting, (2) Code accesses object with ! after await returns, (3) Cancel/dispose operations run concurrently with async operations on same object. Solution: capture local reference before await.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

divinevideo/divine-mobile2652026년 10월 22일 업데이트

Add custom metadata headers (x-amz-meta-*) to AWS v4 signed requests for GCS S3-compatible API. Use when: (1) Adding custom metadata to GCS uploads via S3 API, (2) Getting signature mismatch errors after adding new headers, (3) x-amz-meta-* headers being ignored or causing 403 errors. Custom headers MUST be included in canonical headers and signed headers list.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

divinevideo/divine-mobile2652026년 10월 22일 업데이트

Fix password/secret authentication failures caused by trailing newlines when creating Google Cloud secrets (or similar) with bash here-strings. Use when: (1) Password authentication fails with correct password, (2) Secret created with `<<< "value"` syntax, (3) Error like "password authentication failed" or "invalid token" despite correct value. Bash here-strings (`<<<`) add a trailing newline that corrupts secrets.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

divinevideo/divine-mobile2652026년 10월 22일 업데이트

Fix silent video/media processing failures caused by URL extraction code that filters on file extensions (.mp4, .webm, .webp). Use when: (1) Media moderation, transcoding, or analysis silently skips files from Blossom or content-addressed storage servers, (2) URL extraction from Nostr event tags (imeta, r tags) drops URLs without recognized extensions, (3) CDN fallback URLs append .mp4 but the actual server uses extensionless content-addressed paths like /{sha256}. Common in Nostr video events (kind 34236) where different clients use different URL formats.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

divinevideo/divine-mobile2652026년 10월 22일 업데이트

divinevideo의 스킬 모두 보기

이 스킬의 문제 신고