{"record":{"id":"4d6b9ff6498136a9","repo":"dianping/cat","slug":"w02","errorCode":"W02","errorMessage":"\"{uri}\" already bound to the \"{prefix}\" prefix","messagePattern":"\"(.+?)\" already bound to the \"(.+?)\" prefix","errorType":"validation","errorClass":"StaticWarning","httpStatus":null,"severity":"warning","filePath":"cat-home/src/main/webapp/assets/js/editor/worker-xquery.js","lineNumber":1823,"sourceCode":"            }\n            var namespace = this.getNamespace(uri);\n            if (namespace && namespace.type === type && type !== 'declare' && !namespace.override) {\n                throw new StaticError('XQST0047', '\"' + uri + '\": duplicate target namespace', pos);\n            }\n            namespace = this.getNamespaceByPrefix(prefix);\n            if (namespace && !namespace.override) {\n                throw new StaticError('XQST0033', '\"' + prefix + '\": namespace prefix already bound to \"' + namespace.uri + '\"', pos);\n            }\n\n            namespace = this.namespaces[uri];\n            this.namespaces[uri] = {\n                prefix: prefix,\n                pos: pos,\n                type: type\n            };\n\n            if (namespace) {\n                throw new StaticWarning('W02', '\"' + uri + '\" already bound to the \"' + namespace.prefix + '\" prefix', pos);\n            }\n\n        },\n\n        getNamespaces: function(){\n            return this.root.namespaces;\n        },\n        \n        getNamespace: function (uri) {\n            var that = this;\n            while (that) {\n                var namespace = that.namespaces[uri];\n                if (namespace) {\n                    return namespace;\n                }\n                that = that.parent;\n            }\n","sourceCodeStart":1805,"sourceCodeEnd":1841,"githubUrl":"https://github.com/dianping/cat/blob/e815e74d4c2dd74edac831241f1253fcc7d25381/cat-home/src/main/webapp/assets/js/editor/worker-xquery.js#L1805-L1841","documentation":"W02 is a StaticWarning that the same namespace URI is being bound again to a (new) prefix. After addNamespace() installs the new binding it checks whether a previous entry existed for that URI; if so it warns that the URI was already bound to the old prefix. Unlike XQST0047 this is not fatal — it just signals redundant or potentially confusing double binding.","triggerScenarios":"'declare namespace a = \"U\";' then 'declare namespace b = \"U\";' — the second addNamespace call finds the existing namespaces[uri] entry and warns, having already overwritten the binding.","commonSituations":"Copy-pasted prologs that alias the same module twice; teams standardizing on a new prefix while old code still declares the old one; refactors that add a 'cleaner' prefix without removing the old declaration.","solutions":["Keep one prefix per namespace URI and delete the redundant declaration.","If both prefixes are intentional aliases, accept the warning but document it to avoid reader confusion.","Search the prolog for the URI string to find all competing declarations."],"exampleFix":"// before\ndeclare namespace a = \"http://example.org/mod\";\ndeclare namespace b = \"http://example.org/mod\";\n\n// after\ndeclare namespace a = \"http://example.org/mod\";","handlingStrategy":"validation","validationCode":"// Detect the same URI bound under two prefixes\nvar byUri = {};\nbindings.forEach(function(b) {\n  if (byUri[b.uri] && byUri[b.uri] !== b.prefix) {\n    warn(b.uri + ' already bound as ' + byUri[b.uri]);\n  }\n  byUri[b.uri] = b.prefix;\n});","typeGuard":null,"tryCatchPattern":"if (e.name === 'StaticWarning' && e.code === 'W02') {\n  reportLint(e.pos, e.message);\n}","preventionTips":["One URI, one prefix — enforce via code review or lint.","During prefix migrations, remove old declarations in the same change."],"tags":["xquery","namespace","lint","duplicate"],"backgroundTag":null,"analyzedSha":"e815e74d4c2dd74edac831241f1253fcc7d25381","analyzedAt":"2026-08-14T14:22:34.512Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}