{"record":{"id":"8ab6ad660288daa8","repo":"chenhg5/cc-connect","slug":"yuanbao-platform-located-in-parsed-config-but-not","errorCode":null,"errorMessage":"yuanbao platform located in parsed config but not raw file","messagePattern":"yuanbao platform located in parsed config but not raw file","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"config/config.go","lineNumber":2777,"sourceCode":"\tif platform.Options == nil {\n\t\tplatform.Options = map[string]any{}\n\t}\n\n\tplatform.Options[\"bot_token\"] = botToken\n\n\tallowFrom := strings.TrimSpace(stringOption(platform.Options[\"allow_from\"]))\n\tif v := strings.TrimSpace(opts.AllowFrom); v != \"\" {\n\t\tallowFrom = v\n\t\tplatform.Options[\"allow_from\"] = v\n\t}\n\n\tlines, hadTrailing := splitConfigLines(raw)\n\tspans := buildRawProjectSpans(lines)\n\tif projectIdx >= len(spans) {\n\t\treturn nil, fmt.Errorf(\"project %q located in parsed config but not raw file\", opts.ProjectName)\n\t}\n\tif absIdx >= len(spans[projectIdx].platforms) {\n\t\treturn nil, fmt.Errorf(\"yuanbao platform located in parsed config but not raw file\")\n\t}\n\n\treloadSpan := func() rawPlatformSpan {\n\t\tspans = buildRawProjectSpans(lines)\n\t\treturn spans[projectIdx].platforms[absIdx]\n\t}\n\tspan := reloadSpan()\n\n\tif span.optionsStart < 0 {\n\t\tinsertAt := span.end + 1\n\t\tblock := make([]string, 0, 4)\n\t\tif insertAt > 0 && strings.TrimSpace(lines[insertAt-1]) != \"\" {\n\t\t\tblock = append(block, \"\")\n\t\t}\n\t\tblock = append(block, \"[projects.platforms.options]\")\n\t\tif insertAt < len(lines) && strings.TrimSpace(lines[insertAt]) != \"\" {\n\t\t\tblock = append(block, \"\")\n\t\t}","sourceCodeStart":2759,"sourceCodeEnd":2795,"githubUrl":"https://github.com/chenhg5/cc-connect/blob/4000b2338aa6e850c99df54f8b0ed6ed7460b401/config/config.go#L2759-L2795","documentation":"The sibling of the project-span invariant error: the project span exists but spans[projectIdx].platforms has no entry at absIdx, meaning the raw-line platform-span builder counted fewer platforms inside the project block than the TOML parser did. This is a disagreement between the parsed config model and the line-based raw span model used for in-place text edits.","triggerScenarios":"Platforms inside a [[projects]] block written in a form buildRawProjectSpans misses (inline tables, dotted keys, unusual indentation/headers), so the raw span list is shorter than cfg.Projects[projectIdx].Platforms; a comment or heredoc-like content swallowing a `[[projects.platforms]]` header during line scanning.","commonSituations":"Same as 618 but at platform granularity: a config partially reformatted so some platforms are inline and some are full tables; a third-party tool appending platforms in a non-standard layout.","solutions":["Normalize all platforms in the project to standard `[[projects.platforms]]` blocks via a TOML formatter","Retry the operation after rewriting; if it persists with conventional TOML, file a bug with the config structure (redact tokens)","As a workaround, regenerate the platform entry via the library's add API instead of in-place editing"],"exampleFix":"// before\nplatforms = [{type=\"yuanbao\", bot_token=\"k:s\"}] // inline inside [[projects]]\n// after\n[[projects]]\nname = \"a\"\n[[projects.platforms]]\ntype = \"yuanbao\"\nbot_token = \"k:s\"","handlingStrategy":"try-catch","validationCode":"// internal invariant; no meaningful caller-side pre-check beyond normalizing TOML layout\nif err != nil && strings.Contains(err.Error(), \"not raw file\") {\n    return fmt.Errorf(\"expand inline platform tables into [[projects.platforms]] blocks and retry\")\n}","typeGuard":null,"tryCatchPattern":"if err != nil {\n    if strings.Contains(err.Error(), \"yuanbao platform located in parsed config but not raw file\") {\n        slog.Error(\"raw platform spans out of sync with parsed config; rewrite platform blocks as array-of-tables\", \"err\", err)\n        return err\n    }\n    return err\n}","preventionTips":["Keep every platform as its own [[projects.platforms]] block — no inline tables","Avoid dotted-key platform definitions (projects.platforms.type = ...)","Back up config.toml before automated edits, and retry the operation after reformatting"],"tags":["config","toml","internal","invariant"],"backgroundTag":"internal-invariant-violation","analyzedSha":"4000b2338aa6e850c99df54f8b0ed6ed7460b401","analyzedAt":"2026-09-06T11:45:09.575Z","contentChangedAt":"2026-09-06T11:45:09.575Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}