{"record":{"id":"5cacfdafba86dbcb","repo":"d2lang/d2","slug":"failed-to-recompile-s-w","errorCode":null,"errorMessage":"failed to recompile:\n%s\n%w","messagePattern":"failed to recompile:\n(.+?)\n%w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"d2oracle/edit.go","lineNumber":321,"sourceCode":"\t// We don't want this to be underscore-resolved scope. We want to ignore underscores\n\tvar scopeak []string\n\tif fromScope != g.Root {\n\t\tscopek, err := d2parser.ParseKey(fromScope.AbsID())\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tscopeak = d2graph.Key(scopek)\n\t}\n\treturn pathFromScopeKey(g, key, scopeak)\n}\n\nfunc recompile(g *d2graph.Graph) (*d2graph.Graph, error) {\n\ts := d2format.Format(g.AST)\n\tg2, _, err := d2compiler.Compile(g.AST.Range.Path, strings.NewReader(s), &d2compiler.CompileOptions{\n\t\tFS: g.FS,\n\t})\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to recompile:\\n%s\\n%w\", s, err)\n\t}\n\treturn g2, nil\n}\n\n// TODO merge flat styles\nfunc _set(g *d2graph.Graph, baseAST *d2ast.Map, key string, tag, value *string) error {\n\tif tag != nil {\n\t\tif hasSpace(*tag) {\n\t\t\treturn fmt.Errorf(\"spaces are not allowed in blockstring tags\")\n\t\t}\n\t}\n\n\tmk, err := d2parser.ParseMapKey(key)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tif len(mk.Edges) > 1 {","sourceCodeStart":303,"sourceCodeEnd":339,"githubUrl":"https://github.com/d2lang/d2/blob/0d69dca6f532ceaeacd615d35d1eaa41a238ffdb/d2oracle/edit.go#L303-L339","documentation":"After AST edits, recompile serializes the mutated AST with d2format and recompiles it via d2compiler.Compile. If the edited AST is no longer valid D2 (malformed keys, broken references, invalid values), the compiler error is wrapped as 'failed to recompile:\\n<formatted source>\\n<cause>' so the caller can see both the exact post-edit source and the compiler diagnostics.","triggerScenarios":"Any oracle mutation (Create, Set, ReconnectEdge, Delete, deleteReserved, deleteObjField) that leaves the AST in a state the D2 compiler rejects — e.g. setting a reserved/invalid key value, an edge key referencing a removed object, or malformed key syntax accepted by the parser but not the compiler.","commonSituations":"Setting values of wrong types (e.g. non-numeric into numeric fields); creating keys that collide with reserved words; deleting an object while edges still reference it; invalid blockstring content.","solutions":["Read the embedded post-edit source and compiler message in the wrapped error to find the offending line/key.","Fix the key/value passed to the oracle (correct syntax, valid identifier, type-correct value).","Remove or update references (edges/connections) to deleted objects before/after the mutation.","Validate the desired value against D2 docs (reserved keywords, style value types) before calling Set/Create."],"exampleFix":"// before\ng2, err := d2oracle.Set(g, nil, \"shape\", nil, &str) // invalid value -> recompile fails\n// after\ng2, err := d2oracle.Set(g, nil, \"x.shape\", nil, &str) // valid key + valid scalar value","handlingStrategy":"try-catch","validationCode":"// sanity-check key/value before oracle calls\nif strings.ContainsAny(key, \"\\\"\") { return errors.New(\"invalid key\") }\nif tag != nil && hasSpace(*tag) { return errors.New(\"invalid tag\") }","typeGuard":"func oracleErrRecompile(err error) bool {\n    return err != nil && strings.Contains(err.Error(), \"failed to recompile:\")\n}","tryCatchPattern":"g2, err := d2oracle.Set(g, nil, key, tag, value)\nif oracleErrRecompile(err) {\n    var src, cause string\n    fmt.Sscanf(err.Error(), \"failed to recompile:\\n%[^\\n]\\n%s\", &src, &cause) // inspect post-edit source\n    log.Printf(\"oracle produced invalid D2: %v\", err)\n}","preventionTips":["Use valid D2 identifiers and type-correct values","Remove dangling references before deleting objects","Avoid reserved keywords as keys","Always surface the wrapped compiler message to users"],"tags":["go","d2","compile","ast"],"backgroundTag":"recompile-failed","analyzedSha":"0d69dca6f532ceaeacd615d35d1eaa41a238ffdb","analyzedAt":"2026-08-31T12:19:21.182Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}