{"record":{"id":"f5a2c429d6e35685","repo":"phacility/phabricator","slug":"this-document-is-missing-an-nbformat-field-jupy","errorCode":null,"errorMessage":"This document is missing an \"nbformat\" field. Jupyter notebooks must have this field.","messagePattern":"This document is missing an \"nbformat\" field\\. Jupyter notebooks must have this field\\.","errorType":"exception","errorClass":"Exception","httpStatus":null,"severity":"error","filePath":"src/applications/files/document/PhabricatorJupyterDocumentEngine.php","lineNumber":327,"sourceCode":"      $data = phutil_json_decode($content);\n    } catch (PhutilJSONParserException $ex) {\n      throw new Exception(\n        pht(\n          'This is not a valid JSON document and can not be rendered as '.\n          'a Jupyter notebook: %s.',\n          $ex->getMessage()));\n    }\n\n    if (!is_array($data)) {\n      throw new Exception(\n        pht(\n          'This document does not encode a valid JSON object and can not '.\n          'be rendered as a Jupyter notebook.'));\n    }\n\n    $nbformat = idx($data, 'nbformat');\n    if ($nbformat == null || !strlen($nbformat)) {\n      throw new Exception(\n        pht(\n          'This document is missing an \"nbformat\" field. Jupyter notebooks '.\n          'must have this field.'));\n    }\n\n    if ($nbformat !== 4) {\n      throw new Exception(\n        pht(\n          'This Jupyter notebook uses an unsupported version of the file '.\n          'format (found version %s, expected version 4).',\n          $nbformat));\n    }\n\n    $cells = idx($data, 'cells');\n    if (!is_array($cells)) {\n      throw new Exception(\n        pht(\n          'This Jupyter notebook does not specify a list of \"cells\".'));","sourceCodeStart":309,"sourceCodeEnd":345,"githubUrl":"https://github.com/phacility/phabricator/blob/5720a38cfe95b00ca4be5016dd0d2f3195f4fa04/src/applications/files/document/PhabricatorJupyterDocumentEngine.php#L309-L345","documentation":"The notebook is a JSON object, but the required top-level 'nbformat' field is missing or empty (null or zero-length). The Jupyter engine needs this field to know which notebook specification to apply, so it refuses to render without it.","triggerScenarios":"idx($data, 'nbformat') returns null (key absent) or a value that is null or empty string — e.g. a notebook-like JSON object written by a third-party tool that omits 'nbformat'.","commonSituations":"Custom exporters and converters that emit cells but skip format metadata; hand-written notebook stubs; JSON dictionaries misused as notebooks.","solutions":["Add \"nbformat\": 4 (and typically \"nbformat_minor\") to the top-level notebook object","Re-save the file in a current Jupyter client, which writes the full standard header"],"exampleFix":"{\n  \"metadata\": {},\n  \"cells\": []\n}\n\nafter:\n{\n  \"nbformat\": 4,\n  \"nbformat_minor\": 5,\n  \"metadata\": {},\n  \"cells\": []\n}","handlingStrategy":"validation","validationCode":"$data = json_decode($raw, true);\nif (!is_array($data) || !array_key_exists('nbformat', $data) || $data['nbformat'] === null || $data['nbformat'] === '') {\n  // missing nbformat: reject before rendering\n}","typeGuard":null,"tryCatchPattern":"catch Exception and tell the uploader the notebook header is incomplete; request a re-export from Jupyter.","preventionTips":["Generate notebooks with standard tools so nbformat/nbformat_minor are always written","Validate required notebook fields in pre-upload checks"],"tags":["jupyter","missing-field","schema-validation"],"backgroundTag":"invalid-jupyter-notebook","analyzedSha":"5720a38cfe95b00ca4be5016dd0d2f3195f4fa04","analyzedAt":"2026-08-21T05:07:25.672Z","schemaVersion":2},"datasetVersion":"2026-08-21T11:28:35.574Z"}