{"record":{"id":"a493669be7324b4c","repo":"floci-io/floci","slug":"changesetnotfoundexception","errorCode":"ChangeSetNotFoundException","errorMessage":"ChangeSet [{}] does not exist","messagePattern":"ChangeSet \\[(.+?)\\] does not exist","errorType":"exception","errorClass":"AwsException","httpStatus":400,"severity":"error","filePath":"src/main/java/io/github/hectorvent/floci/services/cloudformation/CloudFormationService.java","lineNumber":192,"sourceCode":"        cs.setChangeSetType(changeSetType != null ? changeSetType : \"CREATE\");\n        cs.setTemplateBody(resolvedTemplate);\n        cs.setParameters(parameters);\n        cs.setCapabilities(capabilities);\n        cs.setStatus(\"CREATE_COMPLETE\");\n        cs.setExecutionStatus(\"AVAILABLE\");\n\n        stack.getChangeSets().put(changeSetName, cs);\n        persistStack(stack);\n        return cs;\n    }\n\n    // ── DescribeChangeSet ─────────────────────────────────────────────────────\n\n    public ChangeSet describeChangeSet(String stackName, String changeSetName, String region) {\n        Stack stack = getStackOrThrow(stackName, region);\n        ChangeSet cs = stack.getChangeSets().get(resolveChangeSetName(changeSetName));\n        if (cs == null) {\n            throw new AwsException(\"ChangeSetNotFoundException\",\n                    \"ChangeSet [\" + changeSetName + \"] does not exist\", 400);\n        }\n        return cs;\n    }\n\n    // ── ExecuteChangeSet ──────────────────────────────────────────────────────\n\n    public Future<?> executeChangeSet(String stackName, String changeSetName, String region) {\n        return executeChangeSet(stackName, changeSetName, region, regionResolver.getAccountId());\n    }\n\n    /**\n     * Executes a change set, provisioning its resources into {@code accountId}'s namespace.\n     *\n     * <p>Provisioning runs on a background executor thread that has no inherited request scope, so\n     * the downstream service calls would otherwise fall back to the default account. The resources\n     * are materialized under a synthetic request scope bound to {@code accountId} so a single-stack\n     * deployment lands in the caller's account, and a StackSet instance lands in its target account.","sourceCodeStart":174,"sourceCodeEnd":210,"githubUrl":"https://github.com/floci-io/floci/blob/62ff490619e7bd3554597c28c704081b4c15add5/src/main/java/io/github/hectorvent/floci/services/cloudformation/CloudFormationService.java#L174-L210","documentation":"DescribeChangeSet found the stack but its changeSets map has no entry under the resolved change-set name. AWS returns ChangeSetNotFoundException for this exact case. Names are resolved via resolveChangeSetName (which may normalize 'arn'-style inputs to the suffix), so a mismatch after resolution also lands here.","triggerScenarios":"aws cloudformation describe-change-set --stack-name s --change-set-name cs where cs was never created on s, was already executed-and-removed, or its arn suffix differs from the supplied name.","commonSituations":"CI pipeline describing a change set after another job deleted it; passing the full ARN when the emulator stored a short name (or vice versa); wrong stack name so the lookup hits an unrelated stack.","solutions":["List the stack's change sets first (aws cloudformation list-change-sets --stack-name s) and use the exact ChangeSetName shown.","Confirm you are targeting the right stack — the change set must be looked up on the stack it belongs to.","If the change set was executed and cleaned up, create a new one before describing."],"exampleFix":"# before\naws cloudformation describe-change-set --stack-name app --change-set-name deploy-v2  # deleted\n# after\naws cloudformation list-change-sets --stack-name app\naws cloudformation describe-change-set --stack-name app --change-set-name <exact-name-from-list>","handlingStrategy":"try-catch","validationCode":"sets = cfn.listChangeSets(StackName=stack)['Summaries']\nknown = {s['ChangeSetName'] for s in sets}\nif csName not in known: raise SystemExit(f'{csName} not on {stack}; have {known}')","typeGuard":"const hasChangeSet = (summaries, name) => summaries.some(s => s.ChangeSetName === name || s.ChangeSetId === name);","tryCatchPattern":"try {\n    cfn.describeChangeSet(StackName=s, ChangeSetName=cs);\n} catch (e) {\n    if (e.code === 'ChangeSetNotFound') { /* recreate set */ }\n    else throw e;\n}","preventionTips":["Use the exact ChangeSetName/Id returned by create-change-set for all follow-up calls.","Scope change-set operations to a single stack in CI to avoid cross-job consumption."],"tags":["cloudformation","changeset","not-found"],"backgroundTag":null,"analyzedSha":"62ff490619e7bd3554597c28c704081b4c15add5","analyzedAt":"2026-08-14T14:25:23.764Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}