{"record":{"id":"050b88439c346528","repo":"conductor-oss/conductor","slug":"failed-to-generate-sqs-policy","errorCode":null,"errorMessage":"Failed to generate SQS policy","messagePattern":"Failed to generate SQS policy","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"awssqs-event-queue/src/main/java/com/netflix/conductor/sqs/eventqueue/SQSObservableQueue.java","lineNumber":313,"sourceCode":"            SqsPolicy policy = new SqsPolicy();\n            policy.setVersion(\"2012-10-17\");\n\n            SqsStatement statement = new SqsStatement();\n            statement.setEffect(\"Allow\");\n            statement.setAction(\"sqs:SendMessage\");\n            statement.setResource(getQueueARN());\n\n            SqsPrincipal principal = new SqsPrincipal();\n            principal.setAws(new ArrayList<>(accountIds));\n            statement.setPrincipal(principal);\n\n            policy.setStatement(List.of(statement));\n\n            ObjectMapper objectMapper = new ObjectMapper();\n            return objectMapper.writeValueAsString(policy);\n        } catch (JsonProcessingException e) {\n            LOGGER.error(\"Failed to generate SQS policy for accounts: {}\", accountIds, e);\n            throw new RuntimeException(\"Failed to generate SQS policy\", e);\n        }\n    }\n\n    private List<String> listQueues(String queueName) {\n        ListQueuesRequest listQueuesRequest =\n                ListQueuesRequest.builder().queueNamePrefix(queueName).build();\n        ListQueuesResponse resultList = client.listQueues(listQueuesRequest);\n        return resultList.queueUrls().stream()\n                .filter(queueUrl -> queueUrl.contains(queueName))\n                .collect(Collectors.toList());\n    }\n\n    private void publishMessages(List<Message> messages) {\n        LOGGER.debug(\"Sending {} messages to the SQS queue: {}\", messages.size(), queueName);\n\n        List<SendMessageBatchRequestEntry> entries =\n                messages.stream()\n                        .map(","sourceCodeStart":295,"sourceCodeEnd":331,"githubUrl":"https://github.com/conductor-oss/conductor/blob/cf7c3e4a8adfb158be778ab1ec525323c363cd3a/awssqs-event-queue/src/main/java/com/netflix/conductor/sqs/eventqueue/SQSObservableQueue.java#L295-L331","documentation":"Thrown by SQSObservableQueue.getPolicy when ObjectMapper.writeValueAsString fails to serialize the SqsPolicy into a JSON string. The policy is built to grant sqs:SendMessage permission to a set of AWS account IDs and is attached to the queue via setQueueAttributes. The underlying JsonProcessingException (a checked Jackson exception) is wrapped in an unchecked RuntimeException, so it propagates through code that does not declare it. It indicates the policy object graph cannot be rendered to JSON at runtime.","triggerScenarios":"Calling getPolicy(List<String> accountIds) with a non-null, non-empty accountIds list when the SqsPolicy/SqsStatement/SqsPrincipal model contains a field type Jackson cannot serialize (e.g. a custom type, circular reference, or missing no-arg constructor / getters). The method is invoked internally during queue initialization when the accountIds property ('conductor.event-queues.sqs.registeredAccountIds' or equivalent) is configured.","commonSituations":"A version change to the SqsPolicy/SqsStatement/SqsPrincipal DTO classes that breaks Jackson serialization (removed getters, added a non-serializable field). A custom/forked policy model with fields Jackson cannot introspect. Extremely unlikely from configuration alone since accountIds is plain List<String>.","solutions":["Inspect the logged cause (the JsonProcessingException) to find which field of SqsPolicy/SqsStatement/SqsPrincipal cannot be serialized.","Verify the SqsPolicy/SqsStatement/SqsPrincipal classes still have public no-arg constructors and standard getters; add @JsonIgnore to non-serializable fields or annotate the problematic property.","If you forked or upgraded the SQS event-queue module, diff the policy DTO classes against a known-working version and restore the serializable shape.","As a workaround, serialize with a ObjectMapper registered with a JavaTimeModule / FAIL_ON_EMPTY_BEANS disabled, but prefer fixing the DTO."],"exampleFix":"// before\nObjectMapper objectMapper = new ObjectMapper();\nreturn objectMapper.writeValueAsString(policy);\n\n// after (defensive config; root cause is usually the DTO shape)\nObjectMapper objectMapper = new ObjectMapper();\nobjectMapper.disable(SerializationFeature.FAIL_ON_EMPTY_BEANS);\nreturn objectMapper.writeValueAsString(policy);","handlingStrategy":"validation","validationCode":"// Validate accountIds are well-formed AWS account IDs before building the policy\nprivate static final java.util.regex.Pattern ACCT =\n    java.util.regex.Pattern.compile(\"^\\\\d{12}$\");\nboolean valid = accountIds != null\n    && accountIds.stream().allMatch(a -> ACCT.matcher(a).matches());\nif (!valid) return null;","typeGuard":null,"tryCatchPattern":"try {\n    queue.getPolicy(accountIds);\n} catch (RuntimeException e) {\n    if (e.getCause() instanceof JsonProcessingException jpe) {\n        log.warn(\"SQS policy serialization failed; check SqsPolicy DTO: {}\", jpe.getOriginalMessage());\n    }\n    throw e;\n}","preventionTips":["Unit-test getPolicy with a realistic accountIds list so DTO regressions surface before deployment.","Keep SqsPolicy/SqsStatement/SqsPrincipal POJOs minimal and getter-based.","Treat RuntimeException from getPolicy as fatal — it means the policy DTO is broken, not a config issue."],"tags":["sqs","aws","json-serialization","jackson","policy"],"backgroundTag":null,"analyzedSha":"cf7c3e4a8adfb158be778ab1ec525323c363cd3a","analyzedAt":"2026-08-14T03:33:19.897Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}