dianping/cat · error · StaticError

XPST0081

XPST0081

Error message

"{prefix}": can not expand prefix of lexical QName to namespace URI

What it means

XPST0081 is the XQuery static error for a lexical QName whose prefix cannot be expanded to a namespace URI. During QName parsing, the worker splits 'prefix:local'; if getPrefixByPrefix finds no binding, the prefix is non-empty, and it is not one of the implicitly known 'fn'/'jn' prefixes, the static error is raised. Q{...}URI-qualified names never hit this path because they carry the URI inline.

Source

Thrown at cat-home/src/main/webapp/assets/js/editor/worker-xquery.js:1880

        },
        
        resolveQName: function(value, pos){
            var qname = {
                uri: '',
                prefix: '',
                name: ''
            };
            var idx;
            if (value.substring(0, 2) === 'Q{') {
                idx = value.indexOf('}');
                qname.uri = value.substring(2, idx);
                qname.name = value.substring(idx + 1);
            } else {
                idx = value.indexOf(':');
                qname.prefix = value.substring(0, idx);
                var namespace = this.getNamespaceByPrefix(qname.prefix);
                if(!namespace && qname.prefix !== '' && ['fn', 'jn'].indexOf(qname.prefix) === -1) {
                    throw new StaticError('XPST0081', '"' + qname.prefix + '": can not expand prefix of lexical QName to namespace URI', pos);
                }
                if(namespace) {
                    qname.uri = namespace.uri;
                }
                qname.name = value.substring(idx + 1);
            }
            return qname;
        },
        
        variables: {},
        varRefs: {},
        functionCalls: {},
    
        addVariable: function(qname, type, pos){
            if(
                type === 'VarDecl' && this.moduleNamespace !== '' &&
                !(this.moduleNamespace === qname.uri || (qname.uri === '' && this.defaultFunctionNamespace === this.moduleNamespace))
            ) {

View on GitHub (pinned to e815e74d4c)

Solutions

  1. Add the missing 'declare namespace prefix = "URI";' or 'import module namespace prefix = "URI";' to the prolog.
  2. Fix the prefix typo (very common with 'xs' vs 'xss', 'local' vs 'locals').
  3. As a robust alternative, use the URI-qualified form 'Q{http://...}name' which needs no prefix binding.

Example fix

// before
let $v := math:sqrt(4) return $v
(: no declare namespace math :)

// after
declare namespace math = "http://www.w3.org/2005/xpath-functions/math";
let $v := math:sqrt(4) return $v
Defensive patterns

Strategy: validation

Validate before calling

// Verify every prefixed name used in the body has a prolog binding
var declared = collectDeclaredPrefixes(prolog); // ['fn','xs','m', ...]
var used = collectUsedPrefixes(body);
var unknown = used.filter(function(p) {
  return declared.indexOf(p) === -1 && ['fn', 'jn'].indexOf(p) === -1;
});
if (unknown.length) { warn('Unbound prefixes: ' + unknown.join(', ')); }

Type guard

function isBoundPrefix(staticContext, prefix) {
  return prefix === '' || prefix === 'fn' || prefix === 'jn' ||
         !!staticContext.getNamespaceByPrefix(prefix);
}

Try / catch

if (e.code === 'XPST0081') {
  highlight(e.pos, 'Add: declare namespace ' + prefix + ' = "..."; or fix the typo');
}

Prevention

When it happens

Trigger: Using foo:bar(...) or foo:bar in the query body when 'declare namespace foo = ...' / a matching import is missing (or is declared after the point of use in module context). Also typos in prefixes of well-known namespaces (e.g. 'xss:...' instead of 'xs:...').

Common situations: Deleting an import but not its call sites; prefix typos; using a module function before importing the module; copied snippets that reference prefixes declared elsewhere; note fn and jn are hardcoded as always-available, other prefixes are not.

Related errors


AI-assisted analysis of dianping/cat@e815e74d4c (2026-08-14). Data as JSON: /api/errors/6c62fc97701cd2ae. Report an issue: GitHub.