{"record":{"id":"4361ff16ffe2fdb2","repo":"windmill-labs/windmill","slug":"wmill-lock-yaml-is-malformed-expected-an-object","errorCode":null,"errorMessage":"wmill-lock.yaml is malformed (expected an object). Refusing to operate to avoid corrupting the lockfile.","messagePattern":"wmill-lock\\.yaml is malformed \\(expected an object\\)\\. Refusing to operate to avoid corrupting the lockfile\\.","errorType":"exception","errorClass":"MalformedLockfileError","httpStatus":null,"severity":"error","filePath":"cli/src/utils/metadata.ts","lineNumber":1252,"sourceCode":"    yamlStringify(inMemoryLock as Record<string, any>, yamlOptions),\n    \"utf-8\",\n  );\n  inMemoryLock = null;\n}\n\nexport async function readLockfile(): Promise<Lock> {\n  if (inMemoryLock) return inMemoryLock;\n  let parsed: unknown;\n  try {\n    parsed = await yamlParseFile(WMILL_LOCKFILE);\n  } catch {\n    const lock: Lock = { locks: {}, version: CURRENT_LOCK_VERSION };\n    await writeFile(WMILL_LOCKFILE, yamlStringify(lock, yamlOptions), \"utf-8\");\n    log.info(colors.green(\"wmill-lock.yaml created\"));\n    return lock;\n  }\n  if (typeof parsed != \"object\" || parsed == null) {\n    throw new MalformedLockfileError(\n      \"wmill-lock.yaml is malformed (expected an object). \" +\n      \"Refusing to operate to avoid corrupting the lockfile.\",\n    );\n  }\n  const conf = parsed as Lock;\n  if (conf.version != null && !KNOWN_LOCK_VERSIONS.includes(conf.version)) {\n    throw new UnknownLockVersionError(\n      `wmill-lock.yaml is at unknown version \"${conf.version}\". This was ` +\n      `written by a newer wmill CLI; please upgrade with \\`wmill upgrade\\`. ` +\n      `Refusing to operate to avoid corrupting the lockfile.`,\n    );\n  }\n  return conf;\n}\n\nfunction v2LockPath(path: string, subpath?: string) {\n  const normalizedPath = normalizeLockPath(path);\n  if (subpath) {","sourceCodeStart":1234,"sourceCodeEnd":1270,"githubUrl":"https://github.com/windmill-labs/windmill/blob/e474e8803ce2ff5c2df09a58dab51d45f5c922ca/cli/src/utils/metadata.ts#L1234-L1270","documentation":"The wmill CLI stores dependency and sync state in wmill-lock.yaml. Before any operation it parses this file; if the parsed YAML is not a non-null object, the CLI throws MalformedLockfileError and refuses to proceed, because writing to a malformed lockfile would destroy user data. This guards against hand-edited or corrupted lockfiles.","triggerScenarios":"Running any wmill command that reads the lockfile (sync, push, pull, deploy, etc.) when wmill-lock.yaml parses to a scalar, array, string, number, or is empty/null instead of a mapping object.","commonSituations":"Manually editing wmill-lock.yaml and accidentally replacing the top-level mapping with a scalar or list; truncating the file during a failed write or git merge conflict; a tool rewriting the file with the wrong root type; checking in an empty or placeholder lockfile.","solutions":["Open wmill-lock.yaml and ensure the top level is a YAML mapping with keys like 'locks' and 'version'","If the file is corrupted or unimportant, delete it and regenerate it with the wmill CLI (e.g. re-run the sync/pull command that recreates the lockfile)","Restore a previous version from git (git checkout -- wmill-lock.yaml) or from a backup","Fix YAML syntax errors such as stray characters, tabs, or unquoted values that cause the document to parse as a scalar"],"exampleFix":"# before (malformed)\nwmill-lock.yaml:\n- just a list\n\n# after (valid)\nversion: 1\nlocks: {}","handlingStrategy":"validation","validationCode":"import { parse } from \"yaml\";\nconst parsed = parse(await readFile(\"wmill-lock.yaml\", \"utf-8\"));\nif (typeof parsed !== \"object\" || parsed === null || Array.isArray(parsed)) {\n  throw new Error(\"wmill-lock.yaml is not an object — restore it from git or delete and regenerate it before running wmill.\");\n}","typeGuard":"function isLockObject(v: unknown): v is Record<string, unknown> {\n  return typeof v === \"object\" && v !== null && !Array.isArray(v);\n}","tryCatchPattern":"try {\n  await wmillSyncPull();\n} catch (e) {\n  if (e instanceof MalformedLockfileError) {\n    // restore from git or delete + regenerate the lockfile\n  } else throw e;\n}","preventionTips":["Don't hand-edit wmill-lock.yaml; let the CLI manage it","Commit the lockfile so a corrupted copy can be restored with git checkout","Add the lockfile to code-review checks so PRs with scalar/empty roots are caught","Never commit an empty or placeholder wmill-lock.yaml"],"tags":["cli","yaml","lockfile","config"],"backgroundTag":"malformed-lockfile","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"}