{"record":{"id":"2968efd6df53327d","repo":"anomalyco/sst","slug":"invalidation-id-not-found","errorCode":null,"errorMessage":"Invalidation ID not found","messagePattern":"Invalidation ID not found","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/server/resource/aws-distribution-invalidation.go","lineNumber":96,"sourceCode":"\t\twildcardEnd := int(math.Min(float64((i+1)*WILDCARD_LIMIT), float64(wildcardCount)))\n\t\tstepPaths := append(pathsFile[fileStart:fileEnd], pathsWildcard[wildcardStart:wildcardEnd]...)\n\n\t\tresult, err := client.CreateInvalidation(r.context, &cloudfront.CreateInvalidationInput{\n\t\t\tDistributionId: aws.String(input.DistributionId),\n\t\t\tInvalidationBatch: &types.InvalidationBatch{\n\t\t\t\tCallerReference: aws.String(strconv.FormatInt(time.Now().UnixNano(), 10)),\n\t\t\t\tPaths: &types.Paths{\n\t\t\t\t\tQuantity: aws.Int32(int32(len(stepPaths))),\n\t\t\t\t\tItems:    stepPaths,\n\t\t\t\t},\n\t\t\t},\n\t\t})\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\tif result.Invalidation == nil || result.Invalidation.Id == nil {\n\t\t\treturn fmt.Errorf(\"Invalidation ID not found\")\n\t\t}\n\n\t\t// Have to wait for invalidation if there are multiple steps\n\t\tif input.Wait || stepsCount > 1 {\n\t\t\twaiter := cloudfront.NewInvalidationCompletedWaiter(client)\n\t\t\terr := waiter.Wait(r.context, &cloudfront.GetInvalidationInput{\n\t\t\t\tDistributionId: aws.String(input.DistributionId),\n\t\t\t\tId:             aws.String(*result.Invalidation.Id),\n\t\t\t}, 10*time.Minute)\n\t\t\tif err != nil {\n\t\t\t\t// Suppress errors\n\t\t\t\t// log.Printf(\"Error waiting for invalidation: %v\", err)\n\t\t\t}\n\t\t}\n\t}\n\n\treturn nil\n}","sourceCodeStart":78,"sourceCodeEnd":114,"githubUrl":"https://github.com/anomalyco/sst/blob/a0bd20f762883e72a35caccb4896c42ce5b3f707/pkg/server/resource/aws-distribution-invalidation.go#L78-L114","documentation":"After calling CloudFront `CreateInvalidation`, the handler validates that the response contains an invalidation with a non-nil Id, which is required to wait for completion. If AWS returns a nil `Invalidation`/`Id` (unexpected response shape), this error is raised for Create/Update of the distribution-invalidation resource.","triggerScenarios":"`cloudfront.CreateInvalidation` succeeds (err == nil) but `result.Invalidation` or `result.Invalidation.Id` is nil — an unexpected/empty AWS API response, e.g. API behavior change, proxy interference, or partial response from a degraded endpoint.","commonSituations":"AWS API outages or regional degradation returning empty bodies; corporate proxies stripping response fields; AWS SDK version mismatches with changed response shapes; retry edge cases in the CloudFront API.","solutions":["Re-run the deploy — transient empty API responses usually resolve on retry","Update the AWS SDK (go.mod aws-sdk-go-v2) and rebuild the CLI to match current API shapes","Check AWS health/dashboard and test `aws cloudfront create-invalidation` manually to compare responses","If behind a proxy/VPN, bypass it and deploy again"],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n  await run(\"sst\", [\"deploy\"]);\n} catch (e) {\n  if (/Invalidation ID not found/.test(String(e))) {\n    await sleep(5000);\n    await run(\"sst\", [\"deploy\"]); // retry; usually a transient empty AWS response\n  } else throw e;\n}","preventionTips":["Keep aws-sdk-go-v2 versions current so response shapes match the live API","Retry invalidation steps on transient API anomalies","Check AWS Health/dashboard before large deploys","Avoid proxies that strip/alter AWS API response bodies"],"tags":["aws","cloudfront","invalidation","api-response"],"backgroundTag":"empty-api-response","analyzedSha":"a0bd20f762883e72a35caccb4896c42ce5b3f707","analyzedAt":"2026-08-30T11:26:00.383Z","schemaVersion":2},"datasetVersion":"2026-08-30T13:17:10.514Z"}