{"record":{"id":"8acb7d32276b9c3e","repo":"iflytek/astron-agent","slug":"key-parse-failed","errorCode":"KEY_PARSE_FAILED","errorMessage":"Lock key parsing failed: ","messagePattern":"Lock key parsing failed: ","errorType":"exception","errorClass":"DistributedLockException","httpStatus":null,"severity":"error","filePath":"console/backend/hub/src/main/java/com/iflytek/astron/console/hub/aspect/DistributedLockAspect.java","lineNumber":158,"sourceCode":"            // This check is a fast path for strings without any dynamic content\n            if (!keyExpression.contains(\"#{\")) {\n                return keyExpression;\n            }\n\n            MethodSignature signature = (MethodSignature) point.getSignature();\n            Method method = signature.getMethod();\n            Object[] args = point.getArgs();\n\n            EvaluationContext context = new MethodBasedEvaluationContext(point.getTarget(), method, args, nameDiscoverer);\n\n            ParserContext parserContext = new TemplateParserContext();\n            Expression expression = parser.parseExpression(keyExpression, parserContext);\n            Object result = expression.getValue(context);\n\n            return result != null ? result.toString() : keyExpression;\n        } catch (Exception e) {\n            log.error(\"Failed to parse lock key: keyExpression={}, error={}\", keyExpression, e.getMessage(), e);\n            throw new DistributedLockException(keyExpression, DistributedLockException.LockErrorType.KEY_PARSE_FAILED, \"Lock key parsing failed: \" + e.getMessage(), e);\n        }\n    }\n\n    /**\n     * Get corresponding lock object based on lock type\n     */\n    private RLock getLock(String lockKey, DistributedLock.LockType lockType) {\n        try {\n            return switch (lockType) {\n                case REENTRANT -> redissonClient.getLock(lockKey);\n                case FAIR -> redissonClient.getFairLock(lockKey);\n                case READ -> {\n                    RReadWriteLock readWriteLock = redissonClient.getReadWriteLock(lockKey);\n                    yield readWriteLock.readLock();\n                }\n                case WRITE -> {\n                    RReadWriteLock readWriteLock = redissonClient.getReadWriteLock(lockKey);\n                    yield readWriteLock.writeLock();","sourceCodeStart":140,"sourceCodeEnd":176,"githubUrl":"https://github.com/iflytek/astron-agent/blob/5e758547a83371a5a4b29dadf4ac03e8dd527635/console/backend/hub/src/main/java/com/iflytek/astron/console/hub/aspect/DistributedLockAspect.java#L140-L176","documentation":"parseLockKey evaluates the @DistributedLock key expression with SpEL and throws DistributedLockException(KEY_PARSE_FAILED) if parsing or evaluation throws. The lock never gets acquired because the lock key itself could not be built.","triggerScenarios":"Key SpEL expression references a null method argument, wrong property name, unsupported syntax, or evaluation throws (e.g. calling a method on null inside the expression).","commonSituations":"Typo in SpEL property (#userId vs #user_id); expression uses a parameter name removed by compilation without -parameters; applying @DistributedLock to a method whose args don't match the expression.","solutions":["Check log 'Failed to parse lock key: keyExpression=...' and fix the SpEL expression","Verify parameter names match actual method signatures (compile with -parameters)","Guard expression operands against null (e.g. #id != null ? #id : 'unknown')","Test the expression with a simple constant key first, then add SpEL gradually"],"exampleFix":"// before\n@DistributedLock(key = \"'bot:' + #req.bot.id\")\npublic void run(Req req) { ... }\n// after\n@DistributedLock(key = \"'bot:' + (#req?.bot?.id ?: 'none')\")\npublic void run(Req req) { ... }","handlingStrategy":"validation","validationCode":"// pre-check SpEL operands: assert args != null && args.getId() != null before invoking the locked method","typeGuard":null,"tryCatchPattern":"try { return service.lockedMethod(arg); } catch (DistributedLockException e) { if (e.getErrorType() == LockErrorType.KEY_PARSE_FAILED) { throw new IllegalStateException(\"bad lock key expression\", e); } throw e; }","preventionTips":["Compile with -parameters so SpEL can resolve argument names","Keep lock key expressions simple; use null-safe navigation (?.) and elvis (?:)","Add a startup/test that evaluates every @DistributedLock key expression"],"tags":["spel","distributed-lock","aop","configuration"],"backgroundTag":"invalid-argument-format","analyzedSha":"5e758547a83371a5a4b29dadf4ac03e8dd527635","analyzedAt":"2026-09-12T08:03:51.356Z","contentChangedAt":"2026-09-12T08:03:51.356Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}