{"record":{"id":"abd6ac826d49047f","repo":"apache/beam","slug":"unsupported-format-for-pubsub-topic-linkedresource","errorCode":null,"errorMessage":"Unsupported format for Pubsub topic: '{linkedResource}'","messagePattern":"Unsupported format for Pubsub topic: '(.+?)'","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"sdks/java/extensions/sql/datacatalog/src/main/java/org/apache/beam/sdk/extensions/sql/meta/provider/datacatalog/PubsubTableFactory.java","lineNumber":56,"sourceCode":"    if (!URI.create(entry.getLinkedResource()).getAuthority().equalsIgnoreCase(PUBSUB_API)) {\n      return Optional.empty();\n    }\n\n    return Optional.of(\n        Table.builder()\n            .location(getLocation(entry))\n            .properties(TableUtils.emptyProperties())\n            .type(\"pubsub\")\n            .comment(\"\"));\n  }\n\n  private static String getLocation(Entry entry) {\n    URI entryName = URI.create(entry.getLinkedResource());\n    String psPath = entryName.getPath();\n\n    Matcher bqPathMatcher = PS_PATH_PATTERN.matcher(psPath);\n    if (!bqPathMatcher.matches()) {\n      throw new IllegalArgumentException(\n          \"Unsupported format for Pubsub topic: '\" + entry.getLinkedResource() + \"'\");\n    }\n\n    return psPath.substring(1);\n  }\n}\n","sourceCodeStart":38,"sourceCodeEnd":63,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/java/extensions/sql/datacatalog/src/main/java/org/apache/beam/sdk/extensions/sql/meta/provider/datacatalog/PubsubTableFactory.java#L38-L63","documentation":"PubsubTableFactory.getLocation throws IllegalArgumentException when a Data Catalog entry's linkedResource URI path does not match the expected Pubsub topic pattern (topics/{project}/{topic}). The path after the first slash is used as the Pubsub location.","triggerScenarios":"entry.getLinkedResource() parses to a URI whose path does not match PS_PATH_PATTERN, e.g. a non-Pubsub linked resource or a malformed topic URL.","commonSituations":"Using a PubsubTableFactory against a GCS fileset entry, a topic URL missing 'topics/', or a linkedResource with subscription instead of topic path.","solutions":["Ensure the entry's linkedResource is a full Pubsub topic URL like projects/_/topics/my-topic (or projects/p/topics/t)","Check the URI path matches 'topics/<project>/<topic>' after the scheme/host","Use the correct TableFactory (GCS) for fileset entries"],"exampleFix":"// before\nlinkedResource: 'https://pubsub.googleapis.com/subscriptions/my-sub'\n// after\nlinkedResource: 'https://pubsub.googleapis.com/projects/my-project/topics/my-topic'","handlingStrategy":"validation","validationCode":"URI uri = URI.create(entry.getLinkedResource());\nString path = uri.getPath();\nif (path == null || !path.matches(\"/topics/[^/]+/[^/]+\")) {\n  throw new IllegalArgumentException(\"Not a Pubsub topic linkedResource: \" + entry.getLinkedResource());\n}","typeGuard":"static boolean isPubsubTopicEntry(Entry e) {\n  String p = URI.create(e.getLinkedResource()).getPath();\n  return p != null && p.startsWith(\"/topics/\");\n}","tryCatchPattern":"try {\n  Table t = pubsubFactory.tableBuilder(entry);\n} catch (IllegalArgumentException ex) {\n  LOG.error(\"linkedResource must be a Pubsub topic URL\", ex);\n}","preventionTips":["Use canonical linkedResource format projects/{project}/topics/{topic}","Distinguish topic vs subscription URLs when creating entries","Apply the right factory per entry type (GCS vs Pubsub)"],"tags":["datacatalog","pubsub","linkedresource"],"backgroundTag":"invalid-url-format","analyzedSha":"12126d8942aaf848030c478b4c6a28c6af861c66","analyzedAt":"2026-09-13T01:50:10.254Z","contentChangedAt":"2026-09-13T01:50:10.254Z","schemaVersion":2},"datasetVersion":"2026-09-20T03:17:13.778Z"}