{"record":{"id":"93ae9b1797b8e555","repo":"BabylonJS/Babylon.js","slug":"projectfile-invalid-project-file-expected-an-ob","errorCode":null,"errorMessage":"ProjectFile: Invalid project file — expected an object.","messagePattern":"ProjectFile: Invalid project file — expected an object\\.","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/dev/sharedUiComponents/src/projects/projectFile.ts","lineNumber":286,"sourceCode":"        }\r\n    } finally {\r\n        // Always restore the render loops, even if loading threw — otherwise\r\n        // the canvas stays frozen forever and the user has no way to recover.\r\n        for (const loop of savedRenderLoops) {\r\n            engine.runRenderLoop(loop);\r\n        }\r\n    }\r\n}\r\n\r\n/**\r\n * Validates and parses a serialized project document.\r\n * @param data - The raw data to validate (typically parsed JSON).\r\n * @returns The validated project document.\r\n * @throws If the data does not conform to the expected schema.\r\n */\r\nexport function DeserializeProject(data: unknown): ISerializedProject {\r\n    if (!data || typeof data !== \"object\") {\r\n        throw new Error(\"ProjectFile: Invalid project file — expected an object.\");\r\n    }\r\n\r\n    const doc = data as Record<string, unknown>;\r\n\r\n    if (doc.version !== 2) {\r\n        throw new Error(`ProjectFile: Unsupported project version \"${doc.version}\". Expected version 2.`);\r\n    }\r\n\r\n    // Validate the asset map portion\r\n    DeserializeSmartAssetMap({ version: 1, assets: doc.assets });\r\n\r\n    // Validate overrides array\r\n    if (!Array.isArray(doc.overrides)) {\r\n        throw new Error(\"ProjectFile: Invalid project file — 'overrides' must be an array.\");\r\n    }\r\n\r\n    // Validate optional companion bindings (shape-only check)\r\n    if (doc.companionBindings !== undefined) {\r","sourceCodeStart":268,"sourceCodeEnd":304,"githubUrl":"https://github.com/BabylonJS/Babylon.js/blob/0592b347b8a4ee0236089ea86a749cacfdb266d8/packages/dev/sharedUiComponents/src/projects/projectFile.ts#L268-L304","documentation":"DeserializeProject is the entry validator for project documents: it requires non-null object input and (next) version === 2. Non-object data means the raw payload isn't a project document at all — usually a parse failure, an error response, or a wrong file fed to the loader.","triggerScenarios":"Calling DeserializeProject(data) with null/undefined, a JSON string (not parsed), an array, or an error object; LoadProjectAsync receiving non-JSON content from the file/input stream.","commonSituations":"Fetching a project from a URL that returned HTML or an error JSON envelope; double-encoding (passing a string instead of parsed JSON); opening a file of the wrong type saved with a project extension.","solutions":["JSON.parse the raw content before calling DeserializeProject.","Verify the fetched/loaded file is actually a project file (check content-type/first bytes).","Confirm doc.version === 2 and fix or migrate files saved with other versions.","Handle fetch/load failures so error responses are not passed to the deserializer."],"exampleFix":"// before\nDeserializeProject(await res.text()); // string, not object\n// after\nconst data = JSON.parse(await res.text());\nDeserializeProject(data); // validated object, version 2","handlingStrategy":"validation","validationCode":"function canDeserializeProject(data) {\n  return !!data && typeof data === \"object\" && !Array.isArray(data) && data.version === 2;\n}\nconst parsed = JSON.parse(raw);\nif (canDeserializeProject(parsed)) DeserializeProject(parsed);","typeGuard":"function isProjectDocument(v: unknown): v is ISerializedProject {\n  return !!v && typeof v === \"object\" && !Array.isArray(v) && (v as any).version === 2;\n}","tryCatchPattern":"// try {\n//   return DeserializeProject(parsed);\n// } catch (e) {\n//   if (String(e.message).includes(\"Invalid project file\")) {\n//     throw new Error(\"Loaded content is not a project document — check the file/endpoint\", { cause: e });\n//   }\n//   throw e;\n// }","preventionTips":["Always JSON.parse before deserializing; never pass raw strings.","Check that fetch endpoints return project JSON, not HTML or error envelopes.","Gate on version === 2 and run migrations for older files before loading."],"tags":["validation","deserialization","schema"],"backgroundTag":"invalid-project-file","analyzedSha":"0592b347b8a4ee0236089ea86a749cacfdb266d8","analyzedAt":"2026-08-30T15:11:20.442Z","schemaVersion":2},"datasetVersion":"2026-08-31T09:17:48.483Z"}