{"record":{"id":"6038910b24a6675b","repo":"windmill-labs/windmill","slug":"expected-local-yaml-path-to-be-an-object-found","errorCode":null,"errorMessage":"Expected local yaml ${path} to be an object, found: ${content} instead","messagePattern":"Expected local yaml (.+?) to be an object, found: (.+?) instead","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"cli/src/commands/sync/sync.ts","lineNumber":649,"sourceCode":"      let parsed: any;\n      try {\n        parsed = yamlParseContent(path, content);\n      } catch (error) {\n        log.error(\n          `Failed to parse YAML content for codebase digest at path: ${path}`,\n        );\n        throw error;\n      }\n      if (parsed && typeof parsed == \"object\") {\n        if (ignoreCodebaseChanges) {\n          parsed[\"codebase\"] = undefined;\n        } else {\n          parsed[\"codebase\"] = await c.getDigest();\n        }\n        parsed[\"lock\"] = \"\";\n        return yamlStringify(parsed, yamlOptions);\n      } else {\n        throw Error(\n          `Expected local yaml ${path} to be an object, found: ${content} instead`,\n        );\n      }\n    }\n  }\n  return content;\n}\n\n/**\n * Whether a script's modules ARE a dbt project.\n *\n * Keyed on `dbt_project.yml` rather than on the descriptor: the descriptor is\n * optional, so its absence says nothing, while a dbt project without\n * `dbt_project.yml` is one dbt itself refuses to run.\n *\n * Its LANGUAGE decides, not its name. A dbt bundle is read verbatim and every\n * file in it is stored as `dbt`; an ordinary modular script that happens to\n * vendor a dbt project stores that same file as whatever its extension infers,","sourceCodeStart":631,"sourceCodeEnd":667,"githubUrl":"https://github.com/windmill-labs/windmill/blob/e474e8803ce2ff5c2df09a58dab51d45f5c922ca/cli/src/commands/sync/sync.ts#L631-L667","documentation":"While updating a local YAML file's codebase digest, sync code expects the file to parse into a top-level object/mapping. If the parsed YAML is a scalar, array or other non-object, addCodebaseDigestIfRelevant throws this error showing the raw content found.","triggerScenarios":"Running wmill sync (addCodebaseDigestIfRelevant) on a local *.yaml file whose content parses to a non-mapping (e.g. an empty file, a plain string, or a list).","commonSituations":"Hand-edited YAML that collapsed to a scalar (missing keys/indentation); an empty .yaml file; a YAML file intended as data, not a Windmill resource definition; YAML anchor/indent mistakes.","solutions":["Fix the YAML so the top level is a mapping (key: value pairs)","If the file should be empty/placeholder, give it valid object content or delete it from the sync folder","Validate the YAML locally (yamllint or a quick parse) to spot the structural break"],"exampleFix":"// before (broken YAML)\njust a string\n// after\nsummary: my resource\nvalue: 42","handlingStrategy":"validation","validationCode":"const parsed = yamlParse(await Deno.readTextFile(path)); if (parsed === null || typeof parsed !== 'object' || Array.isArray(parsed)) throw new Error(`${path} must contain a YAML object`);","typeGuard":"function isYamlObject(v: unknown): v is Record<string, unknown> { return v !== null && typeof v === 'object' && !Array.isArray(v); }","tryCatchPattern":"try { await syncPush(); } catch (e) { if (String(e.message).startsWith('Expected local yaml')) { console.error('Fix the YAML structure named in the error to be a top-level object.'); } else throw e; }","preventionTips":["Run yamllint on the sync folder in CI","Never leave empty or scalar-only .yaml files in a synced folder","Check indentation after hand edits — top level must stay a mapping"],"tags":["yaml","sync","parsing"],"backgroundTag":"yaml-parse-error","analyzedSha":"e474e8803ce2ff5c2df09a58dab51d45f5c922ca","analyzedAt":"2026-09-03T12:38:19.024Z","contentChangedAt":"2026-09-03T12:38:19.024Z","schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}