{"record":{"id":"846a4563dfbde9c6","repo":"floci-io/floci","slug":"badrequestexception-846a45","errorCode":"BadRequestException","errorMessage":"Invalid resource ARN: \" + arn","messagePattern":"Invalid resource ARN: \" \\+ arn","errorType":"validation","errorClass":"AwsException","httpStatus":400,"severity":"error","filePath":"src/main/java/io/github/hectorvent/floci/services/apigateway/ApiGatewayTagHandler.java","lineNumber":56,"sourceCode":"    @Override\n    public Map<String, String> listTags(String region, String arn) {\n        return service.getTags(region, apiIdFromArn(arn));\n    }\n\n    @Override\n    public void tagResource(String region, String arn, Map<String, String> tags) {\n        service.tagResource(region, apiIdFromArn(arn), tags);\n    }\n\n    @Override\n    public void untagResource(String region, String arn, List<String> tagKeys) {\n        service.untagResource(region, apiIdFromArn(arn), tagKeys);\n    }\n\n    private static String apiIdFromArn(String arn) {\n        String[] parts = arn.split(\"/restapis/\");\n        if (parts.length < 2) {\n            throw new AwsException(\"BadRequestException\", \"Invalid resource ARN: \" + arn, 400);\n        }\n        return parts[1].split(\"/\")[0];\n    }\n}\n","sourceCodeStart":38,"sourceCodeEnd":61,"githubUrl":"https://github.com/floci-io/floci/blob/62ff490619e7bd3554597c28c704081b4c15add5/src/main/java/io/github/hectorvent/floci/services/apigateway/ApiGatewayTagHandler.java#L38-L61","documentation":"Thrown by API Gateway v1 tagging operations (TagResource/UntagResource/ListTagsForResource) when the supplied Resource-arn does not contain the literal segment '/restapis/'. Floci's ApiGatewayTagHandler.apiIdFromArn() splits the ARN on '/restapis/' and requires at least two parts; anything else (an ARN for a different resource type, a raw API id, or a malformed string) cannot yield an apiId and is rejected as BadRequestException (HTTP 400).","triggerScenarios":"Calling aws apigateway tag-resource --resource-arn <arn> with an ARN whose resource part is not 'restapis/<apiId>' — e.g. arn:aws:apigateway:us-east-1::/usageplans/abc123, a RestApi id like 'abc123' with no ARN wrapper, or a v2 (HTTP API) ARN of the form ...:/apis/<id> routed at the v1 tagging endpoint.","commonSituations":"Mixing API Gateway v1 (REST) and v2 (HTTP) ARN formats — v2 uses /apis/, not /restapis/. Copying an execute-api ARN, a stage ARN, or passing the API id directly because the console shows it. Tagging usage plans, domain names, or other API Gateway sub-resources whose ARNs this handler does not model.","solutions":["Use the canonical v1 RestApi ARN format: arn:aws:apigateway:<region>::/restapis/<apiId> (empty account field is correct for apigateway).","For HTTP APIs (v2) use the apigatewayv2 TagResource operation and its ARN format arn:aws:apigateway:<region>::/apis/<apiId> instead of the v1 endpoint.","Retrieve the correct ARN from the API's ARN attribute (GetRestApi / Fn::GetAtt RestApi.Arn) rather than hand-building it.","Add a preflight assertion in your tagging code that the ARN contains '/restapis/' before invoking the API."],"exampleFix":"# before\naws --endpoint-url http://localhost:4566 apigateway tag-resource \\\n  --resource-arn arn:aws:apigateway:us-east-1::/apis/abc1234567 --tags k=v\n\n# after (v1 REST API)\naws --endpoint-url http://localhost:4566 apigateway tag-resource \\\n  --resource-arn arn:aws:apigateway:us-east-1::/restapis/abc1234567 --tags k=v","handlingStrategy":"validation","validationCode":"// Java: build and check the v1 ARN before tagging\nString arn = \"arn:aws:apigateway:\" + region + \"::/restapis/\" + apiId;\nif (arn.split(\"/restapis/\").length < 2 || arn.split(\"/restapis/\")[1].isBlank()) {\n    throw new IllegalArgumentException(\"Not a v1 RestApi ARN: \" + arn);\n}\nservice.tagResource(region, arn, tags);","typeGuard":null,"tryCatchPattern":"catch (AwsException e) {\n    if (\"BadRequestException\".equals(e.getCode()) && e.getMessage().contains(\"Invalid resource ARN\")) {\n        // ARN shape is wrong: log and surface a config error, do not retry\n        throw new ConfigurationException(\"Tagging requires arn:aws:apigateway:<region>::/restapis/<apiId>\", e);\n    }\n    throw e;\n}","preventionTips":["Take ARNs from the owning API (GetRestApi's ARN attribute) instead of hand-building them.","Keep v1 (/restapis/) and v2 (/apis/) ARN builders as separate named constants.","Add a shared ARN format unit test for every resource type you tag."],"tags":["apigateway","tagging","arn","validation"],"backgroundTag":null,"analyzedSha":"62ff490619e7bd3554597c28c704081b4c15add5","analyzedAt":"2026-08-14T14:25:23.764Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}