{"id":"0e64f8387e9bf73a","repo":"psycopg/psycopg2","slug":"pg-config-attr-name-is-empty","errorCode":null,"errorMessage":"pg_config --{attr_name} is empty","messagePattern":"pg_config --(.+?) is empty","errorType":"exception","errorClass":"Warning","httpStatus":null,"severity":"critical","filePath":"setup.py","lineNumber":120,"sourceCode":"            sys.exit(1)\n\n    def query(self, attr_name, *, empty_ok=False):\n        \"\"\"Spawn the pg_config executable, querying for the given config\n        name, and return the printed value, sanitized. \"\"\"\n        try:\n            pg_config_process = subprocess.run(\n                [self.pg_config_exe, \"--\" + attr_name],\n                stdout=subprocess.PIPE,\n                stderr=subprocess.PIPE)\n        except OSError:\n            raise Warning(\n                f\"Unable to find 'pg_config' file in '{self.pg_config_exe}'\")\n        if pg_config_process.returncode:\n            err = pg_config_process.stderr.decode(errors='backslashreplace')\n            raise Warning(f\"pg_config --{attr_name} failed: {err}\")\n        result = pg_config_process.stdout.decode().strip()\n        if not result and not empty_ok:\n            raise Warning(f\"pg_config --{attr_name} is empty\")\n        return result\n\n    def find_on_path(self, exename, path_directories=None):\n        if not path_directories:\n            path_directories = os.environ['PATH'].split(os.pathsep)\n        for dir_name in path_directories:\n            fullpath = os.path.join(dir_name, exename)\n            if os.path.isfile(fullpath):\n                return fullpath\n        return None\n\n    def autodetect_pg_config_path(self):\n        \"\"\"Find and return the path to the pg_config executable.\"\"\"\n        if PLATFORM_IS_WINDOWS:\n            return self.autodetect_pg_config_path_windows()\n        else:\n            return self.find_on_path('pg_config')\n","sourceCodeStart":102,"sourceCodeEnd":138,"githubUrl":"https://github.com/psycopg/psycopg2/blob/3a6d9d6ddc6b53eaa80b712f5fa6b23abbdc38db/setup.py#L102-L138","documentation":"Raised in PostgresConfig.query() (setup.py:120) as a Warning when pg_config exited 0 but printed nothing for a required attribute (libdir, includedir, includedir-server). An empty result cannot drive the compiler/linker search paths, so the build aborts. Attributes queried with empty_ok=True (ldflags, cppflags) are exempt and will not trigger this; the required ones will.","triggerScenarios":"During finalize_options(), pg_config_helper.query('libdir') / query('includedir') / query('includedir-server') returns an empty stdout despite exit code 0. Common with a stub or mispackaged pg_config that emits blank lines for some attributes.","commonSituations":"Custom/minimal container images shipping a stripped pg_config; very old or hand-built Postgres installs whose pg_config lacks certain keys; packaging bugs in third-party Postgres distributions.","solutions":["Reinstall the proper PostgreSQL dev package so pg_config emits real paths.","Verify manually: '/path/to/pg_config --includedir' and '--libdir' must each print a non-empty directory.","Fall back to psycopg2-binary if the local pg_config cannot be repaired."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"import subprocess, shutil\n\ndef pg_config_attr_is_nonempty(attr: str, path: str | None = None) -> bool:\n    p = path or shutil.which('pg_config')\n    if not p:\n        return False\n    res = subprocess.run([p, '--' + attr], stdout=subprocess.PIPE, stderr=subprocess.PIPE)\n    return res.returncode == 0 and bool(res.stdout.decode().strip())\n\nfor attr in ('libdir', 'includedir', 'includedir-server'):\n    assert pg_config_attr_is_nonempty(attr), f'pg_config --{attr} returned empty'","typeGuard":null,"tryCatchPattern":"# Pre-build sanity check in CI:\n#   for a in libdir includedir includedir-server; do\n#     v=\"$(pg_config --$a)\"; [ -n \"$v\" ] || { echo \"empty $a\"; exit 1; }\n#   done","preventionTips":["Use official PostgreSQL packages rather than stripped/custom pg_config shims.","After installing the dev package, manually verify pg_config emits non-empty libdir/includedir.","If a minimal image's pg_config is unreliable, switch to psycopg2-binary for the build."],"tags":["psycopg2","build","pg-config","install","environment"],"analyzedSha":"3a6d9d6ddc6b53eaa80b712f5fa6b23abbdc38db","analyzedAt":"2026-08-04T19:56:51.958Z","schemaVersion":2}