{"record":{"id":"282e63bc5a7a11bd","repo":"HMCL-dev/HMCL","slug":"failed-to-download-theme-background-http-respon","errorCode":null,"errorMessage":"Failed to download theme background: HTTP ${responseCode} ${uri}","messagePattern":"Failed to download theme background: HTTP (.+?) (.+?)","errorType":"exception","errorClass":"IOException","httpStatus":null,"severity":"error","filePath":"HMCL/src/main/java/org/jackhuang/hmcl/theme/ThemePackManager.java","lineNumber":1543,"sourceCode":"            return new ThemeBackground.Image(entryName);\n        } finally {\n            if (!success) {\n                try {\n                    deleteIfExists(temporaryFile);\n                } catch (IOException e) {\n                    LOG.warning(\"Failed to delete temporary theme-pack asset: \" + temporaryFile, e);\n                }\n            }\n        }\n    }\n\n    /// Downloads one network background into a temporary file without installing it into the persistent image cache.\n    private static void downloadNetworkBackground(URI uri, Path outputFile) throws IOException {\n        HttpURLConnection connection = NetworkUtils.resolveConnection(NetworkUtils.createHttpConnection(uri));\n        try {\n            int responseCode = connection.getResponseCode();\n            if (responseCode / 100 != 2) {\n                throw new IOException(\"Failed to download theme background: HTTP \" + responseCode + \" \" + uri);\n            }\n\n            ContentEncoding contentEncoding = ContentEncoding.fromConnection(connection);\n            try (InputStream input = contentEncoding.wrap(connection.getInputStream());\n                 OutputStream output = Files.newOutputStream(outputFile)) {\n                IOUtils.copyTo(input, output, new byte[IOUtils.DEFAULT_BUFFER_SIZE]);\n            }\n        } finally {\n            connection.disconnect();\n        }\n    }\n\n    /// Returns a safe theme-pack asset file name for a downloaded network background.\n    private static String networkBackgroundAssetName(URI uri) {\n        String path = Objects.toString(uri.getPath(), \"\");\n        @Nullable Path fileNamePath = path.isBlank() ? null : Path.of(path).getFileName();\n        String fileName = fileNamePath != null ? fileNamePath.toString() : \"\";\n        String sanitized = sanitizePathSegment(fileName);","sourceCodeStart":1525,"sourceCodeEnd":1561,"githubUrl":"https://github.com/HMCL-dev/HMCL/blob/24702dc5a0214034f4c27166d5fd30cad08cec19/HMCL/src/main/java/org/jackhuang/hmcl/theme/ThemePackManager.java#L1525-L1561","documentation":"Thrown by downloadNetworkBackground when the HTTP response code for a theme-pack network background is not in the 2xx range. The method downloads the image to a temporary file and aborts immediately on any non-success status, propagating the code and URI in the message.","triggerScenarios":"Resolving a network background during theme-pack export/import where the server returns 404, 403, 500, etc.; NetworkUtils.resolveConnection succeeds but connection.getResponseCode() / 100 != 2.","commonSituations":"The image URL in the theme manifest no longer exists (404); the host blocks automated downloads (403); a redirect ends at an error page; a CDN or mirror is temporarily failing (5xx); the URL requires authentication.","solutions":["Open the URL in a browser to confirm the status; fix or replace stale 404/403 URLs in the manifest.","Retry later if the server returned 5xx (transient upstream failure).","Switch to an image hosted on a reliable HTTPS host, or bundle the image as a local asset in the pack.","Check that any tokens embedded in the URL are still valid and not expired."],"exampleFix":"// before\n\"background\": { \"url\": \"https://old.example.com/wall.png\" } // 404\n// after\n\"background\": { \"url\": \"https://cdn.example.com/assets/wall.png\" }","handlingStrategy":"retry","validationCode":"// Optionally HEAD-check the URL before export:\nHttpURLConnection c = (HttpURLConnection) URI.create(url).toURL().openConnection();\nc.setRequestMethod(\"HEAD\");\nif (c.getResponseCode() / 100 != 2) throw new IllegalStateException(\"background URL not downloadable: \" + c.getResponseCode());","typeGuard":null,"tryCatchPattern":"try {\n    downloadNetworkBackground(uri, tmp);\n} catch (IOException e) {\n    if (e.getMessage().contains(\"HTTP 5\")) {\n        // transient server error: retry with backoff\n    } else {\n        // 4xx: fix or replace the URL\n    }\n}","preventionTips":["Prefer stable, long-lived CDN URLs over personal or temporary links.","Retry 5xx failures with backoff; treat 4xx as a manifest bug to fix."],"tags":["theme-pack","http","network","download"],"backgroundTag":"http-error-response","analyzedSha":"24702dc5a0214034f4c27166d5fd30cad08cec19","analyzedAt":"2026-09-10T12:36:46.680Z","contentChangedAt":"2026-09-10T12:36:46.680Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}