{"record":{"id":"4ee87079b49f439a","repo":"parcel-bundler/parcel","slug":"genericfailure","errorCode":"GenericFailure","errorMessage":"Could not convert value returned from macro to AST.","messagePattern":"Could not convert value returned from macro to AST\\.","errorType":"exception","errorClass":"napi::Error","httpStatus":null,"severity":"error","filePath":"crates/macros/src/napi.rs","lineNumber":165,"sourceCode":"\n        let names = obj.get_property_names()?;\n        let len = names.get_array_length()?;\n        let mut props = IndexMap::with_capacity(len as usize);\n        for i in 0..len {\n          let prop = names.get_element::<JsString>(i)?;\n          let name = prop.into_utf8()?.into_owned()?;\n          let value = napi_to_js_value(obj.get_property(prop)?, env)?;\n          props.insert(name, value);\n        }\n        Ok(JsValue::Object(props))\n      }\n    }\n    ValueType::Function => {\n      let f = unsafe { value.cast::<JsFunction>() };\n      let source = f.coerce_to_string()?.into_utf8()?.into_owned()?;\n      Ok(JsValue::Function(source))\n    }\n    ValueType::Symbol | ValueType::External | ValueType::Unknown => Err(napi::Error::new(\n      napi::Status::GenericFailure,\n      \"Could not convert value returned from macro to AST.\",\n    )),\n  }\n}\n\nfn await_promise(\n  env: Env,\n  result: JsUnknown,\n  tx: Sender<Result<JsValue, MacroError>>,\n) -> napi::Result<()> {\n  // If the result is a promise, wait for it to resolve, and send the result to the channel.\n  // Otherwise, send the result immediately.\n  if result.is_promise()? {\n    let result: JsObject = result.try_into()?;\n    let then: JsFunction = result.get_named_property(\"then\")?;\n    let tx2 = tx.clone();\n    let cb = env.create_function_from_closure(\"callback\", move |ctx| {","sourceCodeStart":147,"sourceCodeEnd":183,"githubUrl":"https://github.com/parcel-bundler/parcel/blob/59484858a1a0bcbb71f74088956bb437a2db6505/crates/macros/src/napi.rs#L147-L183","documentation":"Returned (as a napi::Error of Status::GenericFailure) by @parcel/macros when napi_to_js_value receives a value whose ValueType is Symbol, External, or Unknown. The macro system can round-trip undefined/null/number/boolean/string/array/object/regex/function, but has no AST representation for these three types, so conversion fails and the error propagates to the JS caller.","triggerScenarios":"A Parcel macro (JS function invoked during transform) returns a value that contains, at any depth, a Symbol, a napi External (native pointer), or a value Node reports as Unknown.","commonSituations":"Macro returns an object with a Symbol-keyed property or a Symbol value (e.g. Symbol.for('x')), returns a class instance whose prototype chain exposes a Symbol, or returns an object embedding a native handle (Buffer internals, FFI).","solutions":["Ensure the macro returns only plain JSON-representable data (strings, numbers, booleans, arrays, plain objects, regexes, functions-as-source).","Strip or stringify any Symbol-keyed/valued properties before returning.","Avoid returning native/external handles; serialize the data you need first."],"exampleFix":"// before\nexport default function macro() {\n  return { id: Symbol('x') };\n}\n// after\nexport default function macro() {\n  return { id: 'x' };\n}","handlingStrategy":"type-guard","validationCode":"function sanitizeForAst(v) {\n  if (typeof v === 'symbol') throw new Error('Cannot return Symbol from macro');\n  if (Array.isArray(v)) return v.map(sanitizeForAst);\n  if (v && typeof v === 'object') {\n    const out = {};\n    for (const [k, val] of Object.entries(v)) out[k] = sanitizeForAst(val);\n    return out;\n  }\n  return v;\n}","typeGuard":"function isMacroSafeValue(v, seen = new WeakSet()) {\n  if (typeof v === 'symbol') return false;\n  if (v === null || typeof v !== 'object') return true;\n  if (seen.has(v)) return false;\n  seen.add(v);\n  return Object.getOwnPropertySymbols(v).length === 0 &&\n    Object.values(v).every(x => isMacroSafeValue(x, seen));\n}","tryCatchPattern":"try {\n  result = macro(...args);\n} catch (e) {\n  if (/Could not convert value returned from macro/.test(e?.message)) {\n    throw new Error('Macro returned a Symbol/External/Unknown value; serialize it first.');\n  }\n  throw e;\n}","preventionTips":["Return only plain JSON-serializable data plus regex/function values from macros.","Strip Symbol keys/values before returning.","Avoid passing native handles or class instances through macro boundaries."],"tags":["macros","rust","napi","ast","parcel"],"backgroundTag":null,"analyzedSha":"59484858a1a0bcbb71f74088956bb437a2db6505","analyzedAt":"2026-08-13T04:06:35.925Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}