dianping/cat · error · StaticError

XPST0008

XPST0008

Error message

"{name}": undeclared variable

What it means

XPST0008 here reports a reference to an undeclared variable. addVarRef() walks the parent static-context chain via getVariable(); if no declaration is found it errors only when qname.uri === '' (unqualified names must resolve locally) or when a moduleResolver is present (imported modules' variables are expected to be resolvable, so an unknown name is a real error). Variables in foreign namespaces are skipped when no resolver exists because they may come from unimported modules.

Source

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

            }
            return variables;
        },
        
        getVariable: function(qname) {
            var key = getVarKey(qname);
            var that = this;
            while(that) {
                if(that.variables[key]) {
                    return that.variables[key];
                }
                that = that.parent;
            }
        },
        
        addVarRef: function(qname, pos){
            var varDecl = this.getVariable(qname);
            if(!varDecl && (qname.uri === '' || this.root.moduleResolver)) {
                throw new StaticError('XPST0008', '"' + qname.name + '": undeclared variable', pos);
            }
            var key = getVarKey(qname);
            this.varRefs[key] = true;
        },
        
        addFunctionCall: function(qname, arity, pos){
            var fn = this.getFunction(qname, arity);
            if(!fn && (qname.uri === 'http://www.w3.org/2005/xquery-local-functions' || this.root.moduleResolver)){
                if((qname.uri === 'http://www.w3.org/2005/xpath-functions' ||
                    (qname.uri === '' && this.root.defaultFunctionNamespaces.concat(this.root.defaultFunctionNamespace).indexOf('http://www.w3.org/2005/xpath-functions') !== -1)) && qname.name === 'concat') {
                } else if(!fn){
                    throw new StaticError('XPST0008', '"' + qname.name + '#' + arity + '": undeclared function', pos);
                }
            }
            var key = getFnKey(qname, arity);
            this.functionCalls[key] = true;
        },
        

View on GitHub (pinned to e815e74d4c)

Solutions

  1. Declare the variable: 'declare variable $foo := ...;' before use.
  2. Fix the reference typo to match the declared name exactly (XQuery names are case-sensitive).
  3. If it comes from a module, import that module and confirm the resolver merges its variables into the static context.
  4. Check spelling of the prefix — a wrong prefix yields a different expanded QName.

Example fix

// before
let $r := $resultCount return $r
(: nothing declares $resultCount :)

// after
declare variable $resultCount as xs:integer := 42;
let $r := $resultCount return $r
Defensive patterns

Strategy: validation

Validate before calling

// Before analysis: every referenced variable must have a declaration or module source
varRefs.forEach(function(ref) {
  if (!declaredVars[ref.uri + '#' + ref.name] &&
      !(ref.uri !== '' && !hasModuleResolver)) {
    warn('Undeclared variable $' + ref.name);
  }
});

Type guard

function isDeclaredVariable(ctx, qname) {
  return !!ctx.getVariable(qname); // walks parent static contexts
}

Try / catch

if (e.code === 'XPST0008' && /variable/.test(e.message)) {
  highlight(e.pos, 'Declare the variable or fix the name — names are case-sensitive');
}

Prevention

When it happens

Trigger: Referencing $foo in the query body with no matching declare variable / import of its module (unqualified case), or referencing $mod:var when a moduleResolver is configured but the imported module does not export that variable.

Common situations: Typos in variable names; using a variable declared in a different module without importing it; deleting a declaration but leaving references; module resolver returning a module whose variables list doesn't cover the referenced name.

Related errors


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