{"record":{"id":"2a797e14c0e2ad0a","repo":"mozilla/pdf.js","slug":"optional-content-properties-malformed","errorCode":null,"errorMessage":"Optional content properties malformed.","messagePattern":"Optional content properties malformed\\.","errorType":"exception","errorClass":"FormatError","httpStatus":null,"severity":"error","filePath":"src/core/evaluator_utils.js","lineNumber":91,"sourceCode":"      currentResult.push(nestedResult);\n      // Recursively parse a subarray.\n      _parseVisibilityExpression(xref, object, nestingCounter, nestedResult);\n    } else if (raw instanceof Ref) {\n      // Reference to an OCG dictionary.\n      currentResult.push(raw.toString());\n    }\n  }\n}\n\nfunction parseMarkedContentProps(xref, contentProperties, resources) {\n  let optionalContent;\n  if (contentProperties instanceof Name) {\n    const properties = resources.get(\"Properties\");\n    optionalContent = properties.get(contentProperties.name);\n  } else if (contentProperties instanceof Dict) {\n    optionalContent = contentProperties;\n  } else {\n    throw new FormatError(\"Optional content properties malformed.\");\n  }\n\n  const optionalContentType = optionalContent.get(\"Type\")?.name;\n  if (optionalContentType === \"OCG\") {\n    return {\n      type: optionalContentType,\n      id: optionalContent.objId,\n    };\n  } else if (optionalContentType === \"OCMD\") {\n    const expression = optionalContent.get(\"VE\");\n    if (Array.isArray(expression)) {\n      const result = [];\n      _parseVisibilityExpression(xref, expression, 0, result);\n      if (result.length > 0) {\n        return {\n          type: \"OCMD\",\n          expression: result,\n        };","sourceCodeStart":73,"sourceCodeEnd":109,"githubUrl":"https://github.com/mozilla/pdf.js/blob/5903d58d58e4dd9ce6ffa3834aea8480f06b4ada/src/core/evaluator_utils.js#L73-L109","documentation":"Thrown by parseMarkedContentProps() when the properties operand of a marked-content operator (e.g. /OC inside a BDC/DP marked-content sequence) is neither a Name (referencing a /Properties resource entry) nor a Dictionary (an inline OCG/OCMD dictionary). Optional Content (layers) require one of these two forms; any other type is malformed. The guard precedes the .get('Type') access that would otherwise throw a TypeError.","triggerScenarios":"A content stream emitting 'BDC' or 'DP' with an optional-content properties operand that is a string, number, null, array, or stream. Fires during operator-list preprocessing when the marked-content tag is /OC and parseMarkedContentProps is invoked. Also possible if /OCMD or /OCG inline dictionaries are malformed upstream.","commonSituations":"PDFs with layers (OCG/OCMD) produced by generators that wrote the properties operand incorrectly, or PDFs damaged in their optional-content region. Common in CAD-exported or layer-heavy engineering PDFs where the OC structure is complex and buggy.","solutions":["Re-export the PDF ensuring the optional-content properties operand is either a Name referencing /Properties or an inline OCG/OCMD dictionary.","Flatten layers before publishing (Acrobat 'Flatten' or Ghostscript) to eliminate the OC marked content entirely.","Isolate the page with per-page try/catch and continue rendering others.","If authoring with layers, validate each BDC/DP /OC operand against the PDF spec section 8.11 before output."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n  await page.render({ canvasContext, viewport });\n} catch (e) {\n  if (e.name === 'FormatError' && /Optional content properties malformed/.test(e.message)) {\n    // bad OC marked-content operand — skip or render without layer info\n  } else throw e;\n}","preventionTips":["Flatten optional-content layers (Acrobat 'Flatten' or Ghostscript) before publishing if layers are not required.","When authoring OC, ensure BDC/DP /OC operands are either a Name (Properties ref) or an inline OCG/OCMD dictionary.","Validate the OC structure against PDF spec section 8.11 in a pre-publish lint step."],"tags":["pdf","optional-content","layers","marked-content","format-error"],"backgroundTag":null,"analyzedSha":"5903d58d58e4dd9ce6ffa3834aea8480f06b4ada","analyzedAt":"2026-08-13T02:28:27.364Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}