Skip to content

fix(serde): handle raw % in README CSS without crashing export#2448

Open
kabhishek1001 wants to merge 1 commit into
mainfrom
fix/readme-decode-percent-in-css
Open

fix(serde): handle raw % in README CSS without crashing export#2448
kabhishek1001 wants to merge 1 commit into
mainfrom
fix/readme-decode-percent-in-css

Conversation

@kabhishek1001
Copy link
Copy Markdown
Collaborator

@kabhishek1001 kabhishek1001 commented Apr 27, 2026

Summary

  • StringUtils.decodeContent calls URLDecoder.decode() on README descriptions during deserialization. When a README contains raw % in inline CSS (e.g. width:100%;), the decoder throws IllegalArgumentException — aborting the entire export with no partial output.
  • Added a catch (IllegalArgumentException e) fallback to return the raw string as-is. Content that was never URL-encoded is already correct; valid %XX sequences are unaffected.
  • Confirmed fix location via full call chain trace: AssetDeserializer.java:336StringUtils.java:96URLDecoder.decode()IllegalArgumentException → caught at LiveAtlanResponseGetter.java:170raiseMalformedJsonError:266 → export exits with code 1.

Root Cause

AssetDeserializer.java:336 calls decodeContent() specifically for Readme type assets:

if (typeName != null && typeName.equals("Readme")) {
    builder.description(StringUtils.decodeContent(builder.build().getDescription()));
}

StringUtils.decodeContent (StringUtils.java:96) had no guard against IllegalArgumentException:

// Before
public static String decodeContent(String encoded) {
    return encoded == null ? null : URLDecoder.decode(encoded.replace("%20", "+"), StandardCharsets.UTF_8);
}

Fix

// After
public static String decodeContent(String encoded) {
    if (encoded == null) return null;
    try {
        return URLDecoder.decode(encoded.replace("%20", "+"), StandardCharsets.UTF_8);
    } catch (IllegalArgumentException e) {
        // README content may contain raw % in CSS (e.g. width:100%;) that was never
        // URL-encoded — return as-is rather than crashing the entire export
        return encoded;
    }
}

Test Plan

  • Existing unit tests pass (./gradlew test)
  • Verify decodeContent("width:100%; border-collapse:collapse; ") returns the raw string without throwing
  • Verify decodeContent("hello+world%21") still returns hello world! (valid URL-encoded content unaffected)
  • Verify decodeContent(null) returns null
  • Run export workflow after deploying — confirm it completes without exit code 1

🤖 Generated with Claude Code

URLDecoder.decode() throws IllegalArgumentException when a README
description contains raw % characters from inline CSS (e.g. width:100%;).
AssetDeserializer calls decodeContent() for every Readme asset during
deserialization, so a single malformed README aborts the entire export.

Catch IllegalArgumentException and fall back to the raw value. Content
that was never URL-encoded is already in its correct form, so this is
safe. Valid URL-encoded sequences (%XX) are unaffected.

Fixes export failures on tenants where READMEs were saved with inline
table styles via the rich-text editor.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Signed-off-by: Kumar Abhishek <kumar.abhishek@atlan.com>
@kabhishek1001 kabhishek1001 requested a review from cmgrote as a code owner April 27, 2026 23:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant