pallets/flask · error · ValueError

If an instance path is provided it must be absolute. A relat

Error message

If an instance path is provided it must be absolute. A relative path was given instead.

What it means

Raised in `Flask.__init__` (src/flask/sansio/app.py:303) when the `instance_path` constructor argument is set but is not an absolute path. Flask's instance folder is used as a filesystem anchor for config files, uploads, and the SQLite-style data that lives outside the package; a relative path would resolve differently depending on the process's current working directory, so Flask refuses it outright instead of guessing.

Source

Thrown at src/flask/sansio/app.py:303

        host_matching: bool = False,
        subdomain_matching: bool = False,
        template_folder: str | os.PathLike[str] | None = "templates",
        instance_path: str | None = None,
        instance_relative_config: bool = False,
        root_path: str | None = None,
    ) -> None:
        super().__init__(
            import_name=import_name,
            static_folder=static_folder,
            static_url_path=static_url_path,
            template_folder=template_folder,
            root_path=root_path,
        )

        if instance_path is None:
            instance_path = self.auto_find_instance_path()
        elif not os.path.isabs(instance_path):
            raise ValueError(
                "If an instance path is provided it must be absolute."
                " A relative path was given instead."
            )

        #: Holds the path to the instance folder.
        #:
        #: .. versionadded:: 0.8
        self.instance_path = instance_path

        #: The configuration dictionary as :class:`Config`.  This behaves
        #: exactly like a regular dictionary but supports additional methods
        #: to load a config from files.
        self.config = self.make_config(instance_relative_config)

        #: An instance of :attr:`aborter_class` created by
        #: :meth:`make_aborter`. This is called by :func:`flask.abort`
        #: to raise HTTP errors, and can be called directly as well.
        #:

View on GitHub ↗ (pinned to 6a2f545bfd)

Solutions

  1. Build the path absolutely from a known anchor, e.g. `os.path.join(os.path.dirname(os.path.abspath(__file__)), 'instance')` or `Path(__file__).parent / 'instance'`.
  2. Wrap externally supplied values with `os.path.abspath(value)` before passing them to Flask if resolving against the current working directory is actually what you intend.
  3. Omit `instance_path` entirely and let Flask auto-detect it next to the package or module.

Example fix

# before
app = Flask(__name__, instance_path="instance")

# after
import os
app = Flask(
    __name__,
    instance_path=os.path.join(os.path.dirname(os.path.abspath(__file__)), "instance"),
)
Defensive patterns

Strategy: validation

Validate before calling

import os
instance_path = os.path.abspath(instance_path)  # ensure absolute
assert os.path.isabs(instance_path)
app = Flask(__name__, instance_path=instance_path)

Type guard

def is_valid_instance_path(p):
    import os
    return isinstance(p, str) and os.path.isabs(p)

Try / catch

try:
    app = Flask(__name__, instance_path=path)
except ValueError as e:
    if 'must be absolute' in str(e):
        app = Flask(__name__, instance_path=os.path.abspath(path))

Prevention

When it happens

Trigger: Calling `Flask(__name__, instance_path='instance')` or any other relative string (e.g. './data', 'config'). Only the explicit-argument branch triggers it — when `instance_path` is omitted, `auto_find_instance_path()` computes an absolute default and this check is skipped.

Common situations: Passing a path copied from a config file or environment variable that was written relative to the project root; constructing the app in a factory and hardcoding 'instance'; Docker/CI setups where an env var like INSTANCE_PATH is set to a relative value; Windows paths like 'C:folder' that are not absolute per os.path.isabs.

Related errors


AI-assisted analysis of pallets/flask@6a2f545bfd (2026-07-31). Data as JSON: /data/errors/9c83c8a0ebab88b5.json. Report an issue: GitHub ↗.