{"record":{"id":"1c4f2cce39d379af","repo":"xpipe-io/xpipe","slug":"parenthostdoesnotsupporttunneling","errorCode":null,"errorMessage":"parentHostDoesNotSupportTunneling","messagePattern":"parentHostDoesNotSupportTunneling","errorType":"validation","errorClass":"ValidationException","httpStatus":null,"severity":"error","filePath":"app/src/main/java/io/xpipe/app/store/NetworkTunnelStore.java","lineNumber":14,"sourceCode":"package io.xpipe.app.store;\n\nimport io.xpipe.app.core.AppI18n;\nimport io.xpipe.app.storage.DataStoreEntryRef;\nimport io.xpipe.app.util.HostAddress;\nimport io.xpipe.app.util.ValidationException;\n\nimport java.util.Optional;\n\npublic interface NetworkTunnelStore extends DataStore, SelfReferentialStore {\n\n    static void checkTunnelable(DataStoreEntryRef<?> ref) throws ValidationException {\n        if (!(ref.getStore() instanceof NetworkTunnelStore t)) {\n            throw new ValidationException(\n                    AppI18n.get(\"parentHostDoesNotSupportTunneling\", ref.get().getName()));\n        }\n\n        var unsupported = t.getUnsupportedParent();\n        if (unsupported.isPresent()) {\n            throw new ValidationException(AppI18n.get(\n                    \"parentHostDoesNotSupportTunneling\", unsupported.get().get().getName()));\n        }\n    }\n\n    DataStoreEntryRef<?> getNetworkParent();\n\n    boolean requiresTunnel();\n\n    default HostAddress getTunnelHostName() {\n        return HostAddress.empty();\n    }\n","sourceCodeStart":1,"sourceCodeEnd":32,"githubUrl":"https://github.com/xpipe-io/xpipe/blob/d85ca821baa46092a320ebb13546d7240adb74f8/app/src/main/java/io/xpipe/app/store/NetworkTunnelStore.java#L1-L32","documentation":"NetworkTunnelStore.checkTunnelable() validates that a data store's parent host is capable of network tunneling. If the referenced store does not implement NetworkTunnelStore, or the tunnel store itself reports an unsupported parent via getUnsupportedParent(), a ValidationException is thrown with the i18n message 'parentHostDoesNotSupportTunneling'. This guards against configuring tunnel-backed connections on hosts that cannot forward traffic.","triggerScenarios":"Calling checkTunnelable(DataStoreEntryRef) with (a) a ref whose store does not implement NetworkTunnelStore (line 14), or (b) a NetworkTunnelStore whose getUnsupportedParent() returns a non-empty Optional (line 20), e.g. the parent host entry is a plain shell/serial connection that lacks tunnel support.","commonSituations":"Selecting a parent host for an SSH-tunnel-backed connection that is itself a local machine, serial connection, or a protocol without port-forwarding; nesting tunnels under a host that disallows forwarding; misconfigured store hierarchy where a non-tunnelable store is set as network parent.","solutions":["Change the connection's network parent to a host store that implements NetworkTunnelStore (e.g. an SSH connection with forwarding enabled)","Enable port forwarding/tunneling on the parent host connection so getUnsupportedParent() returns empty","Remove the tunnel parent (use a direct connection) if tunneling is not actually needed","Verify with the parent's connection settings that the underlying protocol supports TCP forwarding"],"exampleFix":"// before\nDataStoreEntryRef<?> ref = entry.ref(); // ref points to a local shell store\nNetworkTunnelStore.checkTunnelable(ref); // throws ValidationException\n// after\nDataStoreEntryRef<?> ref = sshConnectionEntry.ref(); // SSH host supports tunneling\nNetworkTunnelStore.checkTunnelable(ref); // passes","handlingStrategy":"validation","validationCode":"static boolean isTunnelableParent(DataStoreEntryRef<?> ref) {\n    if (!(ref.getStore() instanceof NetworkTunnelStore t)) return false;\n    return t.getUnsupportedParent().isEmpty();\n}\n// call NetworkTunnelStore.checkTunnelable(ref) only if isTunnelableParent(ref)\n","typeGuard":"boolean ok = ref.getStore() instanceof NetworkTunnelStore t && t.getUnsupportedParent().isEmpty();","tryCatchPattern":null,"preventionTips":["Only assign hosts that implement NetworkTunnelStore as tunnel parents","Verify forwarding support on the parent protocol before configuring a tunnel","Run checkTunnelable() during configuration save, not only at launch","Keep the store hierarchy simple; avoid deep tunnel chains"],"tags":["validation","tunneling","network","configuration"],"backgroundTag":"invalid-argument-value","analyzedSha":"d85ca821baa46092a320ebb13546d7240adb74f8","analyzedAt":"2026-09-06T14:30:08.251Z","contentChangedAt":"2026-09-06T14:30:08.251Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}