{"record":{"id":"54897847d6860578","repo":"t8y2/dbx","slug":"oracle-tns-admin-must-be-a-directory-containing-tn","errorCode":null,"errorMessage":"Oracle TNS_ADMIN must be a directory containing tnsnames.ora: %s","messagePattern":"Oracle TNS_ADMIN must be a directory containing tnsnames\\.ora: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"agents/drivers/oracle-go/tns.go","lineNumber":93,"sourceCode":"\taliases, err := readOracleTNSAliases(tnsNamesPath, make(map[string]bool), 0)\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\tdescriptor, ok := aliases[strings.ToUpper(config.Alias)]\n\tif !ok {\n\t\treturn \"\", fmt.Errorf(\"Oracle TNS alias %q was not found in %s\", config.Alias, tnsNamesPath)\n\t}\n\treturn descriptor, nil\n}\n\nfunc oracleTNSNamesPath(tnsAdmin string) (string, error) {\n\tpath := filepath.Clean(strings.TrimSpace(tnsAdmin))\n\tinfo, err := os.Stat(path)\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"Oracle TNS_ADMIN directory is not accessible: %s\", path)\n\t}\n\tif !info.IsDir() {\n\t\treturn \"\", fmt.Errorf(\"Oracle TNS_ADMIN must be a directory containing tnsnames.ora: %s\", path)\n\t}\n\ttnsNamesPath := filepath.Join(path, \"tnsnames.ora\")\n\tif info, err := os.Stat(tnsNamesPath); err != nil || info.IsDir() {\n\t\treturn \"\", fmt.Errorf(\"Oracle tnsnames.ora was not found in TNS_ADMIN directory: %s\", path)\n\t}\n\treturn tnsNamesPath, nil\n}\n\nfunc readOracleTNSAliases(path string, visited map[string]bool, depth int) (map[string]string, error) {\n\tif depth > 8 {\n\t\treturn nil, fmt.Errorf(\"Oracle TNS include depth exceeds 8 files\")\n\t}\n\tabsolutePath, err := filepath.Abs(path)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"Failed to resolve Oracle TNS file path: %w\", err)\n\t}\n\tif visited[absolutePath] {\n\t\treturn map[string]string{}, nil","sourceCodeStart":75,"sourceCodeEnd":111,"githubUrl":"https://github.com/t8y2/dbx/blob/c0390bff16418b651f4728520d99adf8ce48829a/agents/drivers/oracle-go/tns.go#L75-L111","documentation":"After the TNS_ADMIN path stats successfully, oracleTNSNamesPath checks that it is actually a directory (info.IsDir). A file (e.g. someone set TNS_ADMIN to tnsnames.ora itself) fails this check with this message.","triggerScenarios":"buildDSNForConnect -> resolveOracleTNSAlias -> oracleTNSNamesPath is given a TNS_ADMIN value pointing at a regular file rather than the directory that contains tnsnames.ora.","commonSituations":"Setting TNS_ADMIN to the full path of tnsnames.ora instead of its containing directory; a symlink resolving to a file; config tools substituting a file path variable where a directory was expected.","solutions":["Set TNS_ADMIN to the directory containing tnsnames.ora, not the file itself: /opt/oracle/network/admin not /opt/oracle/network/admin/tnsnames.ora.","Verify with ls -ld that the path is a directory (d in permissions).","Fix any config templating that appends 'tnsnames.ora' to the value.","Check symlinks resolve to a directory (readlink -f <path>)."],"exampleFix":"// before\ndsn := \"jdbc:oracle:thin:@ALIAS?TNS_ADMIN=/opt/oracle/network/admin/tnsnames.ora\" // file path\n// after\ndsn := \"jdbc:oracle:thin:@ALIAS?TNS_ADMIN=/opt/oracle/network/admin\"","handlingStrategy":"validation","validationCode":"info, err := os.Stat(tnsAdmin)\nif err == nil && !info.IsDir() {\n\treturn errors.New(\"TNS_ADMIN must be the directory containing tnsnames.ora, not the file itself\")\n}","typeGuard":null,"tryCatchPattern":"if strings.Contains(err.Error(), \"must be a directory\") {\n\t// strip a trailing tnsnames.ora component and retry once\n\tdir := filepath.Dir(tnsAdmin)\n}","preventionTips":["Configure TNS_ADMIN as a directory path, never a file path.","Use filepath.Dir if you only have the tnsnames.ora path.","Verify with os.Stat + IsDir in config validation at startup."],"tags":["oracle","tns","filesystem","config"],"backgroundTag":"invalid-path","analyzedSha":"c0390bff16418b651f4728520d99adf8ce48829a","analyzedAt":"2026-09-05T23:05:10.900Z","contentChangedAt":"2026-09-05T23:05:10.900Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}